aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--bootstrap/bin/start.bootbin5306 -> 5324 bytes
-rw-r--r--bootstrap/bin/start.script30
-rw-r--r--bootstrap/bin/start_clean.bootbin5306 -> 5324 bytes
-rw-r--r--bootstrap/bin/start_clean.script30
-rw-r--r--bootstrap/lib/compiler/ebin/beam_asm.beambin9168 -> 9028 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_block.beambin13040 -> 12964 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bool.beambin14928 -> 14880 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_bsm.beambin12308 -> 12196 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_clean.beambin10192 -> 10128 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_dead.beambin10908 -> 11456 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_disasm.beambin23216 -> 23268 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_flatten.beambin3256 -> 3252 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_jump.beambin8984 -> 8936 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_opcodes.beambin6652 -> 6756 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_peep.beambin3176 -> 2356 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_receive.beambin0 -> 5392 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_trim.beambin7764 -> 7764 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_type.beambin13260 -> 13016 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_utils.beambin13096 -> 12776 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/beam_validator.beambin31480 -> 31328 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl.beambin28432 -> 28236 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_inline.beambin33288 -> 33288 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/cerl_trees.beambin15848 -> 15824 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compile.beambin31748 -> 31408 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/compiler.app1
-rw-r--r--bootstrap/lib/compiler/ebin/core_lib.beambin5068 -> 5072 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_lint.beambin10660 -> 10656 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_parse.beambin34380 -> 34380 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_pp.beambin11204 -> 11148 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/core_scan.beambin6276 -> 6268 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/erl_bifs.beambin2024 -> 2100 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/rec_env.beambin4412 -> 4312 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_core_fold.beambin41672 -> 42184 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_expand_pmod.beambin7608 -> 7616 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/sys_pre_expand.beambin14064 -> 14156 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_codegen.beambin48048 -> 47904 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_core.beambin45100 -> 44984 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_kernel.beambin40832 -> 40832 bytes
-rw-r--r--bootstrap/lib/compiler/ebin/v3_life.beambin21600 -> 21568 bytes
-rw-r--r--bootstrap/lib/compiler/egen/beam_opcodes.erl12
-rw-r--r--bootstrap/lib/compiler/egen/core_parse.erl33
-rw-r--r--bootstrap/lib/kernel/ebin/application_controller.beambin28712 -> 27960 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_master.beambin5940 -> 5944 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/application_starter.beambin1260 -> 1204 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/auth.beambin5912 -> 5908 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code.beambin5744 -> 5716 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/code_server.beambin23856 -> 23736 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log.beambin37120 -> 36428 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_1.beambin22836 -> 22820 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/disk_log_server.beambin5952 -> 5948 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_ac.beambin24808 -> 24776 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/dist_util.beambin9436 -> 9536 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_boot_server.beambin5272 -> 5268 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_ddll.beambin2456 -> 2464 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erl_epmd.beambin7668 -> 7644 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/error_handler.beambin1864 -> 1828 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/erts_debug.beambin2640 -> 2608 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file.beambin11012 -> 11224 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file_io_server.beambin12836 -> 13004 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/file_server.beambin4852 -> 4828 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/gen_sctp.beambin3144 -> 3144 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global.beambin29500 -> 29332 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global_group.beambin16296 -> 16224 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/global_search.beambin2768 -> 2768 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/group.beambin10580 -> 10884 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/heart.beambin3644 -> 3624 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet.beambin18228 -> 17984 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet6_tcp_dist.beambin5792 -> 5856 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_config.beambin8304 -> 8280 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_db.beambin24836 -> 24716 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_dns.beambin18484 -> 18712 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_gethost_native.beambin9748 -> 9680 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_parse.beambin11980 -> 11968 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_res.beambin14260 -> 14216 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_tcp_dist.beambin6112 -> 6116 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/inet_udp.beambin1812 -> 1808 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel.beambin3564 -> 3556 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/kernel_config.beambin2572 -> 2556 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net_adm.beambin2864 -> 2864 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/net_kernel.beambin21048 -> 21308 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/os.beambin4648 -> 4644 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/packages.beambin2100 -> 2096 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/pg2.beambin6948 -> 6984 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/ram_file.beambin6084 -> 6512 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/rpc.beambin8200 -> 8204 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/standard_error.beambin3472 -> 3460 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user.beambin11356 -> 11460 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/user_drv.beambin9480 -> 9324 bytes
-rw-r--r--bootstrap/lib/kernel/ebin/wrap_log_reader.beambin3220 -> 3156 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/array.beambin10720 -> 10720 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/base64.beambin3836 -> 3828 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/beam_lib.beambin16168 -> 16528 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/binary.beambin0 -> 2480 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/c.beambin12664 -> 12520 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets.beambin49020 -> 48608 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_utils.beambin26024 -> 26012 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v8.beambin25388 -> 25152 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dets_v9.beambin46524 -> 46124 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/dict.beambin8596 -> 8604 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph.beambin7684 -> 7664 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/digraph_utils.beambin6228 -> 6252 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/edlin.beambin7296 -> 7392 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/epp.beambin21656 -> 21816 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_bits.beambin2468 -> 2468 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_compile.beambin4744 -> 4736 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_eval.beambin21624 -> 21588 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_expand_records.beambin17056 -> 19756 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_internal.beambin3912 -> 4852 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_lint.beambin72444 -> 76548 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_parse.beambin62156 -> 64988 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_pp.beambin21332 -> 21540 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_scan.beambin30300 -> 30204 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/erl_tar.beambin14648 -> 14600 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_file_h.beambin4596 -> 4588 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/error_logger_tty_h.beambin4332 -> 4332 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/escript.beambin15328 -> 15284 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ets.beambin18516 -> 18080 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/eval_bits.beambin6140 -> 6136 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/file_sorter.beambin28356 -> 28320 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filelib.beambin6376 -> 6388 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/filename.beambin8672 -> 8644 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gb_sets.beambin7520 -> 7544 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gb_trees.beambin4612 -> 4624 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen.beambin3456 -> 3412 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_event.beambin11880 -> 12356 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_fsm.beambin8600 -> 9056 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/gen_server.beambin11336 -> 11948 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io.beambin6176 -> 6176 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib.beambin8308 -> 8300 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_format.beambin10948 -> 10964 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/io_lib_pretty.beambin11280 -> 11260 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lib.beambin8104 -> 8100 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/lists.beambin27512 -> 27432 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/ms_transform.beambin16884 -> 16896 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/otp_internal.beambin7192 -> 7768 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/pg.beambin1936 -> 1932 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/pool.beambin3520 -> 3520 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proc_lib.beambin8476 -> 8472 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/proplists.beambin4576 -> 4560 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc.beambin64404 -> 64200 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/qlc_pt.beambin66008 -> 65996 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/re.beambin11312 -> 11296 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/regexp.beambin7896 -> 7860 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sets.beambin6736 -> 6736 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/shell.beambin28144 -> 28160 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sofs.beambin39096 -> 39076 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/stdlib.app1
-rw-r--r--bootstrap/lib/stdlib/ebin/supervisor.beambin15184 -> 14984 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/sys.beambin6860 -> 6804 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/timer.beambin4836 -> 4732 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/unicode.beambin10792 -> 10808 bytes
-rw-r--r--bootstrap/lib/stdlib/ebin/zip.beambin24644 -> 24568 bytes
-rw-r--r--bootstrap/lib/stdlib/egen/erl_parse.erl13555
-rw-r--r--erts/aclocal.m495
-rw-r--r--erts/configure.in7
-rw-r--r--erts/doc/src/erl.xml36
-rw-r--r--erts/doc/src/erl_nif.xml428
-rw-r--r--erts/doc/src/erlang.xml74
-rw-r--r--erts/doc/src/match_spec.xml54
-rw-r--r--erts/emulator/Makefile.in17
-rw-r--r--erts/emulator/beam/atom.names9
-rw-r--r--erts/emulator/beam/beam_emu.c155
-rw-r--r--erts/emulator/beam/beam_load.c88
-rw-r--r--erts/emulator/beam/bif.c48
-rw-r--r--erts/emulator/beam/bif.tab36
-rw-r--r--erts/emulator/beam/binary.c57
-rw-r--r--erts/emulator/beam/break.c2
-rw-r--r--erts/emulator/beam/copy.c130
-rw-r--r--erts/emulator/beam/erl_alloc.types1
-rw-r--r--erts/emulator/beam/erl_bif_binary.c2930
-rw-r--r--erts/emulator/beam/erl_bif_guard.c37
-rw-r--r--erts/emulator/beam/erl_bif_info.c17
-rw-r--r--erts/emulator/beam/erl_bif_port.c4
-rw-r--r--erts/emulator/beam/erl_bif_timer.c2
-rw-r--r--erts/emulator/beam/erl_binary.h25
-rw-r--r--erts/emulator/beam/erl_db_util.c17
-rw-r--r--erts/emulator/beam/erl_debug.c6
-rw-r--r--erts/emulator/beam/erl_gc.c101
-rw-r--r--erts/emulator/beam/erl_gc.h39
-rw-r--r--erts/emulator/beam/erl_init.c54
-rw-r--r--erts/emulator/beam/erl_message.c133
-rw-r--r--erts/emulator/beam/erl_message.h27
-rw-r--r--erts/emulator/beam/erl_nif.c384
-rw-r--r--erts/emulator/beam/erl_nif.h38
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h68
-rw-r--r--erts/emulator/beam/erl_port_task.c8
-rw-r--r--erts/emulator/beam/erl_process.c77
-rw-r--r--erts/emulator/beam/erl_process.h2
-rw-r--r--erts/emulator/beam/erl_threads.h14
-rw-r--r--erts/emulator/beam/erl_trace.c4
-rw-r--r--erts/emulator/beam/erl_vm.h4
-rw-r--r--erts/emulator/beam/global.h13
-rw-r--r--erts/emulator/beam/io.c26
-rw-r--r--erts/emulator/beam/ops.tab59
-rw-r--r--erts/emulator/beam/register.c37
-rw-r--r--erts/emulator/beam/sys.h18
-rw-r--r--erts/emulator/beam/utils.c5
-rw-r--r--erts/emulator/drivers/common/efile_drv.c57
-rw-r--r--erts/emulator/drivers/common/erl_efile.h13
-rw-r--r--erts/emulator/drivers/common/inet_drv.c77
-rw-r--r--erts/emulator/drivers/common/ram_file_drv.c17
-rw-r--r--erts/emulator/drivers/unix/unix_efile.c22
-rw-r--r--erts/emulator/drivers/win32/win_efile.c31
-rw-r--r--erts/emulator/hipe/hipe_gc.c18
-rw-r--r--erts/emulator/sys/common/erl_poll.c59
-rw-r--r--erts/emulator/sys/unix/erl9_start.c130
-rw-r--r--erts/emulator/sys/win32/erl_poll.c65
-rw-r--r--erts/emulator/sys/win32/sys.c124
-rw-r--r--erts/emulator/test/Makefile4
-rw-r--r--erts/emulator/test/bif_SUITE.erl22
-rw-r--r--erts/emulator/test/binary_SUITE.erl10
-rw-r--r--erts/emulator/test/busy_port_SUITE.erl15
-rw-r--r--erts/emulator/test/distribution_SUITE.erl11
-rw-r--r--erts/emulator/test/fun_r12_SUITE.erl1
-rw-r--r--erts/emulator/test/guard_SUITE.erl179
-rw-r--r--erts/emulator/test/nif_SUITE.erl254
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c738
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.c80
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_mod.h12
-rw-r--r--erts/emulator/test/port_SUITE.erl13
-rw-r--r--erts/emulator/test/receive_SUITE.erl113
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl11
-rw-r--r--erts/epmd/src/epmd_int.h4
-rw-r--r--erts/epmd/src/epmd_srv.c19
-rw-r--r--erts/include/internal/ethread.h66
-rw-r--r--erts/include/internal/ethread_header_config.h.in23
-rw-r--r--erts/include/internal/gcc/ethr_atomic.h164
-rw-r--r--erts/include/internal/gcc/ethread.h30
-rw-r--r--erts/include/internal/i386/atomic.h20
-rw-r--r--erts/include/internal/ppc32/atomic.h11
-rw-r--r--erts/include/internal/sparc32/atomic.h14
-rw-r--r--erts/include/internal/tile/atomic.h2
-rw-r--r--erts/lib_src/Makefile.in2
-rw-r--r--erts/lib_src/common/ethread.c37
-rw-r--r--erts/preloaded/ebin/erl_prim_loader.beambin50816 -> 50384 bytes
-rw-r--r--erts/preloaded/ebin/erlang.beambin23808 -> 24320 bytes
-rw-r--r--erts/preloaded/ebin/init.beambin44500 -> 44352 bytes
-rw-r--r--erts/preloaded/ebin/otp_ring0.beambin1448 -> 1432 bytes
-rw-r--r--erts/preloaded/ebin/prim_file.beambin29496 -> 30452 bytes
-rw-r--r--erts/preloaded/ebin/prim_inet.beambin57320 -> 57268 bytes
-rw-r--r--erts/preloaded/ebin/prim_zip.beambin22600 -> 22432 bytes
-rw-r--r--erts/preloaded/ebin/zlib.beambin10620 -> 10616 bytes
-rw-r--r--erts/preloaded/src/erl_prim_loader.erl5
-rw-r--r--erts/preloaded/src/erlang.erl13
-rw-r--r--erts/preloaded/src/prim_file.erl52
-rw-r--r--lib/appmon/src/appmon.erl15
-rw-r--r--lib/appmon/src/appmon_info.erl21
-rw-r--r--lib/appmon/src/appmon_place.erl14
-rw-r--r--lib/asn1/c_src/Makefile2
-rw-r--r--lib/common_test/src/ct_ssh.erl26
-rw-r--r--lib/common_test/vsn.mk2
-rw-r--r--lib/compiler/doc/src/compile.xml61
-rw-r--r--lib/compiler/src/Makefile1
-rw-r--r--lib/compiler/src/beam_asm.erl21
-rw-r--r--lib/compiler/src/beam_block.erl1
-rw-r--r--lib/compiler/src/beam_bool.erl21
-rw-r--r--lib/compiler/src/beam_dead.erl58
-rw-r--r--lib/compiler/src/beam_disasm.erl33
-rw-r--r--lib/compiler/src/beam_peep.erl58
-rw-r--r--lib/compiler/src/beam_receive.erl388
-rw-r--r--lib/compiler/src/beam_type.erl4
-rw-r--r--lib/compiler/src/beam_utils.erl16
-rw-r--r--lib/compiler/src/beam_validator.erl10
-rw-r--r--lib/compiler/src/cerl.erl13
-rw-r--r--lib/compiler/src/cerl_inline.erl7
-rw-r--r--lib/compiler/src/cerl_trees.erl16
-rw-r--r--lib/compiler/src/compile.erl31
-rw-r--r--lib/compiler/src/compiler.app.src11
-rw-r--r--lib/compiler/src/erl_bifs.erl12
-rw-r--r--lib/compiler/src/genop.tab8
-rw-r--r--lib/compiler/src/rec_env.erl12
-rw-r--r--lib/compiler/src/sys_core_fold.erl45
-rw-r--r--lib/compiler/src/sys_pre_expand.erl28
-rw-r--r--lib/compiler/src/v3_core.erl47
-rw-r--r--lib/compiler/src/v3_kernel.erl19
-rw-r--r--lib/compiler/src/v3_life.erl2
-rw-r--r--lib/compiler/test/andor_SUITE.erl24
-rw-r--r--lib/compiler/test/bs_match_SUITE.erl24
-rw-r--r--lib/compiler/test/compile_SUITE.erl46
-rw-r--r--lib/compiler/test/compiler.cover2
-rw-r--r--lib/compiler/test/core_SUITE_data/.gitignore1
-rw-r--r--lib/compiler/test/error_SUITE.erl166
-rw-r--r--lib/compiler/test/float_SUITE.erl24
-rw-r--r--lib/compiler/test/guard_SUITE.erl146
-rw-r--r--lib/compiler/test/match_SUITE.erl15
-rw-r--r--lib/compiler/test/misc_SUITE.erl90
-rw-r--r--lib/compiler/test/receive_SUITE.erl63
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl99
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl26
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl14
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl12
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl13
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl16
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl16
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl46
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl15
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl12
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl15
-rw-r--r--lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl13
-rw-r--r--lib/compiler/test/test_lib.erl40
-rw-r--r--lib/crypto/c_src/crypto.c32
-rw-r--r--lib/debugger/src/dbg_ui_trace_win.erl32
-rw-r--r--lib/debugger/src/dbg_ui_win.erl15
-rwxr-xr-xlib/debugger/src/dbg_wx_trace_win.erl10
-rw-r--r--lib/dialyzer/src/dialyzer_analysis_callgraph.erl68
-rw-r--r--lib/dialyzer/src/dialyzer_behaviours.erl13
-rw-r--r--lib/dialyzer/src/dialyzer_callgraph.erl2
-rw-r--r--lib/dialyzer/src/dialyzer_cl.erl37
-rw-r--r--lib/dialyzer/src/dialyzer_codeserver.erl46
-rw-r--r--lib/dialyzer/src/dialyzer_contracts.erl28
-rw-r--r--lib/dialyzer/src/dialyzer_dataflow.erl2
-rw-r--r--lib/dialyzer/src/dialyzer_plt.erl69
-rw-r--r--lib/dialyzer/src/dialyzer_races.erl3
-rw-r--r--lib/dialyzer/src/dialyzer_utils.erl27
-rw-r--r--lib/gs/src/tool_utils.erl23
-rw-r--r--lib/hipe/cerl/erl_types.erl215
-rw-r--r--lib/hipe/flow/hipe_dominators.erl12
-rw-r--r--lib/hipe/icode/hipe_beam_to_icode.erl29
-rw-r--r--lib/hipe/icode/hipe_icode.erl32
-rw-r--r--lib/hipe/util/hipe_digraph.erl12
-rw-r--r--lib/ic/doc/src/Makefile16
-rw-r--r--lib/ic/doc/src/notes.xml22
-rw-r--r--lib/ic/vsn.mk6
-rw-r--r--lib/inets/doc/src/http_server.xml13
-rw-r--r--lib/inets/doc/src/notes.xml55
-rw-r--r--lib/inets/src/http_client/httpc_cookie.erl12
-rw-r--r--lib/inets/src/http_lib/http_util.erl106
-rw-r--r--lib/inets/src/http_server/httpd_instance_sup.erl6
-rw-r--r--lib/inets/src/http_server/httpd_sup.erl10
-rw-r--r--lib/inets/src/http_server/httpd_util.erl21
-rw-r--r--lib/inets/src/inets_app/inets.appup.src20
-rw-r--r--lib/inets/src/inets_app/inets.erl2
-rw-r--r--lib/inets/test/http_format_SUITE.erl16
-rw-r--r--lib/inets/vsn.mk17
-rw-r--r--lib/kernel/doc/src/file.xml46
-rw-r--r--lib/kernel/src/code.erl2
-rw-r--r--lib/kernel/src/dist_util.erl15
-rw-r--r--lib/kernel/src/file.erl37
-rw-r--r--lib/kernel/src/file_io_server.erl16
-rw-r--r--lib/kernel/src/group.erl48
-rw-r--r--lib/kernel/src/inet.erl2
-rw-r--r--lib/kernel/src/inet_dns.erl44
-rw-r--r--lib/kernel/src/inet_res.erl11
-rw-r--r--lib/kernel/src/net_kernel.erl203
-rw-r--r--lib/kernel/src/os.erl31
-rw-r--r--lib/kernel/src/pg2.erl4
-rw-r--r--lib/kernel/src/ram_file.erl48
-rw-r--r--lib/kernel/test/file_SUITE.erl187
-rw-r--r--lib/kernel/test/os_SUITE.erl7
-rw-r--r--lib/kernel/test/pg2_SUITE.erl135
-rw-r--r--lib/kernel/test/prim_file_SUITE.erl95
-rw-r--r--lib/megaco/doc/src/megaco.xml16
-rw-r--r--lib/megaco/doc/src/notes.xml39
-rw-r--r--lib/megaco/src/app/megaco.appup.src10
-rw-r--r--lib/megaco/src/app/megaco_internal.hrl26
-rw-r--r--lib/megaco/src/engine/megaco_config.erl26
-rw-r--r--lib/megaco/src/engine/megaco_messenger.erl239
-rw-r--r--lib/megaco/src/engine/megaco_monitor.erl33
-rw-r--r--lib/megaco/src/flex/Makefile.in2
-rw-r--r--lib/megaco/vsn.mk2
-rw-r--r--lib/mnesia/src/mnesia_controller.erl37
-rw-r--r--lib/mnesia/src/mnesia_lib.erl10
-rw-r--r--lib/mnesia/src/mnesia_recover.erl10
-rw-r--r--lib/mnesia/src/mnesia_schema.erl33
-rw-r--r--lib/odbc/test/Makefile114
-rw-r--r--lib/odbc/test/README86
-rw-r--r--lib/odbc/test/odbc.dynspec31
-rw-r--r--lib/odbc/test/odbc.spec9
-rw-r--r--lib/odbc/test/odbc.spec.win5
-rw-r--r--lib/odbc/test/odbc_connect_SUITE.erl816
-rw-r--r--lib/odbc/test/odbc_data_type_SUITE.erl1498
-rw-r--r--lib/odbc/test/odbc_query_SUITE.erl1453
-rw-r--r--lib/odbc/test/odbc_start_SUITE.erl147
-rw-r--r--lib/odbc/test/odbc_test.hrl37
-rw-r--r--lib/odbc/test/odbc_test_lib.erl77
-rw-r--r--lib/odbc/test/oracle.erl246
-rw-r--r--lib/odbc/test/postgres.erl294
-rw-r--r--lib/odbc/test/sqlserver.erl298
-rw-r--r--lib/parsetools/src/leex.erl53
-rw-r--r--lib/public_key/asn1/OTP-PKIX.asn12
-rw-r--r--lib/public_key/src/pubkey_cert.erl33
-rw-r--r--lib/public_key/src/pubkey_cert_records.erl398
-rw-r--r--lib/public_key/src/pubkey_pem.erl16
-rw-r--r--lib/public_key/src/public_key.erl4
-rw-r--r--lib/public_key/test/Makefile6
-rw-r--r--lib/public_key/test/pkey_test.erl412
-rw-r--r--lib/public_key/test/public_key.cover2
-rw-r--r--lib/public_key/test/public_key_SUITE.erl238
-rw-r--r--lib/public_key/vsn.mk11
-rw-r--r--lib/snmp/doc/src/notes.xml70
-rw-r--r--lib/snmp/doc/src/snmp_app.xml2
-rw-r--r--lib/snmp/doc/src/snmp_config.xml2
-rw-r--r--lib/snmp/doc/src/snmpa.xml36
-rw-r--r--lib/snmp/doc/src/snmpa_mpd.xml42
-rw-r--r--lib/snmp/src/agent/snmpa.erl23
-rw-r--r--lib/snmp/src/agent/snmpa_agent.erl230
-rw-r--r--lib/snmp/src/agent/snmpa_internal.hrl12
-rw-r--r--lib/snmp/src/agent/snmpa_mib.erl12
-rw-r--r--lib/snmp/src/agent/snmpa_mpd.erl226
-rw-r--r--lib/snmp/src/agent/snmpa_trap.erl95
-rw-r--r--lib/snmp/src/agent/snmpa_usm.erl74
-rw-r--r--lib/snmp/src/app/snmp.appup.src188
-rw-r--r--lib/snmp/src/manager/snmpm_mpd.erl24
-rw-r--r--lib/snmp/src/manager/snmpm_server.erl26
-rw-r--r--lib/snmp/test/snmp_agent_test.erl19
-rw-r--r--lib/snmp/test/snmp_agent_test_lib.erl12
-rw-r--r--lib/snmp/vsn.mk173
-rw-r--r--lib/ssh/doc/src/notes.xml12
-rw-r--r--lib/ssh/src/ssh_acceptor.erl4
-rw-r--r--lib/ssh/src/ssh_cli.erl6
-rwxr-xr-xlib/ssh/src/ssh_connect.hrl3
-rw-r--r--lib/ssh/src/ssh_connection.erl20
-rw-r--r--lib/ssh/src/ssh_connection_controler.erl4
-rw-r--r--lib/ssh/src/ssh_connection_handler.erl7
-rw-r--r--lib/ssh/src/ssh_connection_manager.erl7
-rw-r--r--lib/ssh/src/ssh_sftpd.erl9
-rw-r--r--lib/ssh/vsn.mk4
-rw-r--r--lib/ssl/doc/src/new_ssl.xml19
-rw-r--r--lib/ssl/src/ssl.erl57
-rw-r--r--lib/ssl/src/ssl_alert.erl60
-rw-r--r--lib/ssl/src/ssl_certificate.erl8
-rw-r--r--lib/ssl/src/ssl_cipher.erl525
-rw-r--r--lib/ssl/src/ssl_cipher.hrl70
-rw-r--r--lib/ssl/src/ssl_connection.erl594
-rw-r--r--lib/ssl/src/ssl_handshake.erl373
-rw-r--r--lib/ssl/src/ssl_handshake.hrl15
-rw-r--r--lib/ssl/src/ssl_internal.hrl1
-rw-r--r--lib/ssl/src/ssl_manager.erl37
-rw-r--r--lib/ssl/src/ssl_record.erl188
-rw-r--r--lib/ssl/src/ssl_record.hrl6
-rw-r--r--lib/ssl/src/ssl_session_cache.erl16
-rw-r--r--lib/ssl/src/ssl_session_cache_api.erl12
-rw-r--r--lib/ssl/src/ssl_ssl3.erl71
-rw-r--r--lib/ssl/src/ssl_sup.erl33
-rw-r--r--lib/ssl/src/ssl_tls1.erl75
-rw-r--r--lib/ssl/test/ssl.cover14
-rw-r--r--lib/ssl/test/ssl_basic_SUITE.erl798
-rw-r--r--lib/ssl/test/ssl_to_openssl_SUITE.erl155
-rw-r--r--lib/ssl/vsn.mk4
-rw-r--r--lib/stdlib/doc/src/Makefile11
-rw-r--r--lib/stdlib/doc/src/beam_lib.xml7
-rw-r--r--lib/stdlib/doc/src/binary.xml729
-rw-r--r--lib/stdlib/doc/src/gen_event.xml64
-rw-r--r--lib/stdlib/doc/src/gen_fsm.xml64
-rw-r--r--lib/stdlib/doc/src/gen_server.xml61
-rw-r--r--lib/stdlib/doc/src/lists.xml6
-rw-r--r--lib/stdlib/doc/src/re.xml6
-rw-r--r--lib/stdlib/doc/src/ref_man.xml7
-rw-r--r--lib/stdlib/src/Makefile1
-rw-r--r--lib/stdlib/src/beam_lib.erl37
-rw-r--r--lib/stdlib/src/binary.erl177
-rw-r--r--lib/stdlib/src/dets.erl11
-rw-r--r--lib/stdlib/src/digraph.erl12
-rw-r--r--lib/stdlib/src/edlin.erl5
-rw-r--r--lib/stdlib/src/epp.erl55
-rw-r--r--lib/stdlib/src/erl_compile.erl12
-rw-r--r--lib/stdlib/src/erl_expand_records.erl132
-rw-r--r--lib/stdlib/src/erl_internal.erl151
-rw-r--r--lib/stdlib/src/erl_lint.erl441
-rw-r--r--lib/stdlib/src/erl_parse.yrl54
-rw-r--r--lib/stdlib/src/erl_pp.erl35
-rw-r--r--lib/stdlib/src/erl_scan.erl47
-rw-r--r--lib/stdlib/src/ets.erl2
-rw-r--r--lib/stdlib/src/file_sorter.erl9
-rw-r--r--lib/stdlib/src/gen.erl45
-rw-r--r--lib/stdlib/src/gen_event.erl29
-rw-r--r--lib/stdlib/src/gen_fsm.erl38
-rw-r--r--lib/stdlib/src/gen_server.erl38
-rw-r--r--lib/stdlib/src/io.erl11
-rw-r--r--lib/stdlib/src/io_lib.erl2
-rw-r--r--lib/stdlib/src/io_lib_fread.erl12
-rw-r--r--lib/stdlib/src/lists.erl3
-rw-r--r--lib/stdlib/src/proc_lib.erl12
-rw-r--r--lib/stdlib/src/proplists.erl12
-rw-r--r--lib/stdlib/src/stdlib.app.src11
-rw-r--r--lib/stdlib/src/supervisor.erl172
-rw-r--r--lib/stdlib/src/timer.erl66
-rw-r--r--lib/stdlib/test/Makefile2
-rw-r--r--lib/stdlib/test/binary_module_SUITE.erl1323
-rw-r--r--lib/stdlib/test/binref.erl588
-rw-r--r--lib/stdlib/test/dummy1_h.erl15
-rw-r--r--lib/stdlib/test/epp_SUITE.erl62
-rw-r--r--lib/stdlib/test/erl_lint_SUITE.erl224
-rw-r--r--lib/stdlib/test/erl_pp_SUITE.erl36
-rw-r--r--lib/stdlib/test/erl_scan_SUITE.erl5
-rw-r--r--lib/stdlib/test/gen_event_SUITE.erl59
-rw-r--r--lib/stdlib/test/gen_fsm_SUITE.erl67
-rw-r--r--lib/stdlib/test/gen_server_SUITE.erl115
-rw-r--r--lib/stdlib/test/io_proto_SUITE.erl1
-rw-r--r--lib/stdlib/test/qlc_SUITE.erl15
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl5
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl6
-rw-r--r--lib/syntax_tools/src/erl_recomment.erl9
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl1
-rw-r--r--lib/syntax_tools/src/erl_syntax_lib.erl7
-rw-r--r--lib/syntax_tools/src/igor.erl22
-rw-r--r--lib/syntax_tools/src/prettypr.erl2
-rw-r--r--lib/test_server/src/test_server_node.erl1
-rw-r--r--lib/test_server/vsn.mk2
-rw-r--r--lib/tools/emacs/Makefile1
-rw-r--r--lib/tools/emacs/README9
-rw-r--r--lib/tools/emacs/erlang-eunit.el94
-rw-r--r--lib/tools/emacs/erlang-flymake.el102
-rw-r--r--lib/tools/emacs/erlang-start.el5
-rw-r--r--lib/tools/emacs/erlang.el261
-rw-r--r--lib/tools/emacs/test.erl.indented79
-rw-r--r--lib/tools/emacs/test.erl.orig83
-rw-r--r--lib/tools/src/xref_base.erl174
-rw-r--r--lib/tools/src/xref_compiler.erl133
-rw-r--r--lib/tools/src/xref_reader.erl52
-rw-r--r--lib/tools/test/xref_SUITE.erl334
-rw-r--r--lib/tools/test/xref_SUITE_data/read/read.erl12
-rw-r--r--lib/tv/src/tv_io_lib_format.erl17
-rw-r--r--lib/tv/src/tv_pb.erl37
-rw-r--r--lib/tv/src/tv_pg_gridfcns.erl59
-rw-r--r--lib/wx/c_src/Makefile.in2
-rw-r--r--lib/wx/src/wx_object.erl71
-rw-r--r--system/doc/reference_manual/expressions.xml97
-rw-r--r--xcomp/erl-xcomp-mips-linux.conf258
519 files changed, 31304 insertions, 12459 deletions
diff --git a/bootstrap/bin/start.boot b/bootstrap/bin/start.boot
index 940541dbf8..71d72c4b7d 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 7fe0b03498..1b7e8ae4f7 100644
--- a/bootstrap/bin/start.script
+++ b/bootstrap/bin/start.script
@@ -1,4 +1,4 @@
-%% script generated at {2010,4,1} {7,43,29}
+%% script generated at {2010,6,2} {16,55,39}
{script,
{"OTP APN 181 01","R14A"},
[{preLoaded,
@@ -24,7 +24,7 @@
standard_error,user,user_drv,user_sup,wrap_log_reader]},
{path,["$ROOT/lib/stdlib/ebin"]},
{primLoad,
- [array,base64,beam_lib,c,calendar,dets,dets_server,dets_sup,
+ [array,base64,beam_lib,binary,c,calendar,dets,dets_server,dets_sup,
dets_utils,dets_v8,dets_v9,dict,digraph,digraph_utils,edlin,
edlin_expand,epp,erl_bits,erl_compile,erl_eval,erl_expand_records,
erl_internal,erl_lint,erl_parse,erl_posix_msg,erl_pp,erl_scan,
@@ -83,19 +83,19 @@
{vsn,"1.17"},
{id,[]},
{modules,
- [array,base64,beam_lib,c,calendar,dets,dets_server,
- dets_sup,dets_utils,dets_v8,dets_v9,dict,digraph,
- digraph_utils,edlin,edlin_expand,epp,eval_bits,
- erl_bits,erl_compile,erl_eval,erl_expand_records,
- erl_internal,erl_lint,erl_parse,erl_posix_msg,erl_pp,
- erl_scan,erl_tar,error_logger_file_h,
- error_logger_tty_h,escript,ets,file_sorter,filelib,
- filename,gb_trees,gb_sets,gen,gen_event,gen_fsm,
- gen_server,io,io_lib,io_lib_format,io_lib_fread,
- io_lib_pretty,lib,lists,log_mf_h,math,ms_transform,
- orddict,ordsets,otp_internal,pg,pool,proc_lib,
- proplists,qlc,qlc_pt,queue,random,re,regexp,sets,
- shell,shell_default,slave,sofs,string,supervisor,
+ [array,base64,beam_lib,binary,c,calendar,dets,
+ dets_server,dets_sup,dets_utils,dets_v8,dets_v9,dict,
+ digraph,digraph_utils,edlin,edlin_expand,epp,
+ eval_bits,erl_bits,erl_compile,erl_eval,
+ erl_expand_records,erl_internal,erl_lint,erl_parse,
+ erl_posix_msg,erl_pp,erl_scan,erl_tar,
+ error_logger_file_h,error_logger_tty_h,escript,ets,
+ file_sorter,filelib,filename,gb_trees,gb_sets,gen,
+ gen_event,gen_fsm,gen_server,io,io_lib,io_lib_format,
+ io_lib_fread,io_lib_pretty,lib,lists,log_mf_h,math,
+ ms_transform,orddict,ordsets,otp_internal,pg,pool,
+ proc_lib,proplists,qlc,qlc_pt,queue,random,re,regexp,
+ sets,shell,shell_default,slave,sofs,string,supervisor,
supervisor_bridge,sys,timer,unicode,win32reg,zip]},
{registered,
[timer_server,rsh_starter,take_over_monitor,
diff --git a/bootstrap/bin/start_clean.boot b/bootstrap/bin/start_clean.boot
index 940541dbf8..71d72c4b7d 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 7fe0b03498..1b7e8ae4f7 100644
--- a/bootstrap/bin/start_clean.script
+++ b/bootstrap/bin/start_clean.script
@@ -1,4 +1,4 @@
-%% script generated at {2010,4,1} {7,43,29}
+%% script generated at {2010,6,2} {16,55,39}
{script,
{"OTP APN 181 01","R14A"},
[{preLoaded,
@@ -24,7 +24,7 @@
standard_error,user,user_drv,user_sup,wrap_log_reader]},
{path,["$ROOT/lib/stdlib/ebin"]},
{primLoad,
- [array,base64,beam_lib,c,calendar,dets,dets_server,dets_sup,
+ [array,base64,beam_lib,binary,c,calendar,dets,dets_server,dets_sup,
dets_utils,dets_v8,dets_v9,dict,digraph,digraph_utils,edlin,
edlin_expand,epp,erl_bits,erl_compile,erl_eval,erl_expand_records,
erl_internal,erl_lint,erl_parse,erl_posix_msg,erl_pp,erl_scan,
@@ -83,19 +83,19 @@
{vsn,"1.17"},
{id,[]},
{modules,
- [array,base64,beam_lib,c,calendar,dets,dets_server,
- dets_sup,dets_utils,dets_v8,dets_v9,dict,digraph,
- digraph_utils,edlin,edlin_expand,epp,eval_bits,
- erl_bits,erl_compile,erl_eval,erl_expand_records,
- erl_internal,erl_lint,erl_parse,erl_posix_msg,erl_pp,
- erl_scan,erl_tar,error_logger_file_h,
- error_logger_tty_h,escript,ets,file_sorter,filelib,
- filename,gb_trees,gb_sets,gen,gen_event,gen_fsm,
- gen_server,io,io_lib,io_lib_format,io_lib_fread,
- io_lib_pretty,lib,lists,log_mf_h,math,ms_transform,
- orddict,ordsets,otp_internal,pg,pool,proc_lib,
- proplists,qlc,qlc_pt,queue,random,re,regexp,sets,
- shell,shell_default,slave,sofs,string,supervisor,
+ [array,base64,beam_lib,binary,c,calendar,dets,
+ dets_server,dets_sup,dets_utils,dets_v8,dets_v9,dict,
+ digraph,digraph_utils,edlin,edlin_expand,epp,
+ eval_bits,erl_bits,erl_compile,erl_eval,
+ erl_expand_records,erl_internal,erl_lint,erl_parse,
+ erl_posix_msg,erl_pp,erl_scan,erl_tar,
+ error_logger_file_h,error_logger_tty_h,escript,ets,
+ file_sorter,filelib,filename,gb_trees,gb_sets,gen,
+ gen_event,gen_fsm,gen_server,io,io_lib,io_lib_format,
+ io_lib_fread,io_lib_pretty,lib,lists,log_mf_h,math,
+ ms_transform,orddict,ordsets,otp_internal,pg,pool,
+ proc_lib,proplists,qlc,qlc_pt,queue,random,re,regexp,
+ sets,shell,shell_default,slave,sofs,string,supervisor,
supervisor_bridge,sys,timer,unicode,win32reg,zip]},
{registered,
[timer_server,rsh_starter,take_over_monitor,
diff --git a/bootstrap/lib/compiler/ebin/beam_asm.beam b/bootstrap/lib/compiler/ebin/beam_asm.beam
index 2db98a2013..23046bac9f 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 e494c90788..4d71b65e23 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 a1ff7e705d..ef6e7823cc 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 87bdc81d1e..fb331ee690 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 9127a20bda..0b28815f2a 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 bdba7d1bfd..56288dc79e 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_disasm.beam b/bootstrap/lib/compiler/ebin/beam_disasm.beam
index c1fe43b398..c8e2b27623 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 8546e1233a..402f2a14ae 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 2643874e07..1ee7b725fb 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_opcodes.beam b/bootstrap/lib/compiler/ebin/beam_opcodes.beam
index 34327c700e..6ded472cb0 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 9fcb2536c8..279dd272b5 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_receive.beam b/bootstrap/lib/compiler/ebin/beam_receive.beam
new file mode 100644
index 0000000000..4d88e80acd
--- /dev/null
+++ b/bootstrap/lib/compiler/ebin/beam_receive.beam
Binary files differ
diff --git a/bootstrap/lib/compiler/ebin/beam_trim.beam b/bootstrap/lib/compiler/ebin/beam_trim.beam
index 74b0cec2f6..5c0d405843 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 769c1d3b40..cccf58b7a4 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 51975f77d4..7b9c08439e 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 2edf5f226e..6af598519f 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 b0fef4fd1a..9f45f9f441 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_inline.beam b/bootstrap/lib/compiler/ebin/cerl_inline.beam
index 430f5e72b5..e0cfce01ae 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 49fb42c1c6..d46cfe54b7 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 f989cdc1df..3db3a08335 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 497d1873d8..ed0dd7c30e 100644
--- a/bootstrap/lib/compiler/ebin/compiler.app
+++ b/bootstrap/lib/compiler/ebin/compiler.app
@@ -33,6 +33,7 @@
beam_listing,
beam_opcodes,
beam_peep,
+ beam_receive,
beam_trim,
beam_type,
beam_utils,
diff --git a/bootstrap/lib/compiler/ebin/core_lib.beam b/bootstrap/lib/compiler/ebin/core_lib.beam
index 43c29138b8..8796f7e13e 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 75e8b9b162..e7db1d3f72 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 19202ce827..631c5d6aba 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 94baecf93c..fb9001c52f 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 d9a088f4c6..cd2146d722 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 8132234cb1..128f8a88d2 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 9e3d93482e..8a1de81396 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_fold.beam b/bootstrap/lib/compiler/ebin/sys_core_fold.beam
index 10686ad92c..f780a2fae6 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_expand_pmod.beam b/bootstrap/lib/compiler/ebin/sys_expand_pmod.beam
index c0b1ebd802..3323279d7d 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_expand.beam b/bootstrap/lib/compiler/ebin/sys_pre_expand.beam
index 2333028391..7b4d278e30 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 d55373f6ac..5555d01b2a 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 1905ab5660..5d889ea4f3 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 2f3efc7dfb..f87360f259 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_life.beam b/bootstrap/lib/compiler/ebin/v3_life.beam
index 3b39cffbf9..3f0a409447 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 83cdaa4d48..fda227f90f 100644
--- a/bootstrap/lib/compiler/egen/beam_opcodes.erl
+++ b/bootstrap/lib/compiler/egen/beam_opcodes.erl
@@ -8,7 +8,7 @@
-spec format_number() -> 0.
format_number() -> 0.
--spec opcode(atom(), 0..8) -> 1..149.
+-spec opcode(atom(), 0..8) -> 1..152.
opcode(label, 1) -> 1;
opcode(func_info, 3) -> 2;
opcode(int_code_end, 0) -> 3;
@@ -118,7 +118,7 @@ opcode(try_case, 1) -> 106;
opcode(try_case_end, 1) -> 107;
opcode(raise, 2) -> 108;
opcode(bs_init2, 6) -> 109;
-opcode(bs_bits_to_bytes, 3) -> 110;
+%%opcode(bs_bits_to_bytes, 3) -> 110;
opcode(bs_add, 5) -> 111;
opcode(apply, 1) -> 112;
opcode(apply_last, 2) -> 113;
@@ -158,9 +158,12 @@ opcode(bs_utf16_size, 3) -> 146;
opcode(bs_put_utf16, 3) -> 147;
opcode(bs_put_utf32, 3) -> 148;
opcode(on_load, 0) -> 149;
+opcode(recv_mark, 1) -> 150;
+opcode(recv_set, 1) -> 151;
+opcode(gc_bif3, 7) -> 152;
opcode(Name, Arity) -> erlang:error(badarg, [Name,Arity]).
--spec opname(1..149) -> {atom(),0..8}.
+-spec opname(1..152) -> {atom(),0..8}.
opname(1) -> {label,1};
opname(2) -> {func_info,3};
opname(3) -> {int_code_end,0};
@@ -310,4 +313,7 @@ opname(146) -> {bs_utf16_size,3};
opname(147) -> {bs_put_utf16,3};
opname(148) -> {bs_put_utf32,3};
opname(149) -> {on_load,0};
+opname(150) -> {recv_mark,1};
+opname(151) -> {recv_set,1};
+opname(152) -> {gc_bif3,7};
opname(Number) -> erlang:error(badarg, [Number]).
diff --git a/bootstrap/lib/compiler/egen/core_parse.erl b/bootstrap/lib/compiler/egen/core_parse.erl
index 05624beb14..9740cb91bb 100644
--- a/bootstrap/lib/compiler/egen/core_parse.erl
+++ b/bootstrap/lib/compiler/egen/core_parse.erl
@@ -13,7 +13,7 @@
tok_val(T) -> element(3, T).
tok_line(T) -> element(2, T).
--file("/usr/local/otp/releases/sles10_32_R13B04_patched/lib/parsetools-2.0.2/include/yeccpre.hrl", 0).
+-file("/usr/local/otp/releases/otp_beam_linux_sles10_x64_r13b02_patched/lib/parsetools-2.0/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
@@ -36,32 +36,33 @@ tok_line(T) -> element(2, T).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
- yecc_ret().
+-spec(parse_and_scan/1 ::
+ ({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(any()) -> [char() | list()].
+-spec(format_error/1 :: (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(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/2 :: (integer(), any()) -> no_return()).
return_error(Line, Message) ->
throw({error, {Line, ?MODULE, Message}}).
@@ -100,7 +101,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} ->
@@ -133,7 +134,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) ->
@@ -194,7 +195,7 @@ yecctoken2string(Other) ->
--file("/clearcase/otp/erts/bootstrap/lib/compiler/egen/core_parse.erl", 197).
+-file("/ldisk/pan/git/otp/bootstrap/lib/compiler/egen/core_parse.erl", 198).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
diff --git a/bootstrap/lib/kernel/ebin/application_controller.beam b/bootstrap/lib/kernel/ebin/application_controller.beam
index 51e1222578..113faeda01 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 1d82fcd682..602dc36104 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 542ef99f18..405d2f388a 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 9fc133efe7..3c038f87aa 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 1392a018ab..bca88dfe7c 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 e662c95922..8f95f91348 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 86927f1125..b432811d6e 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 942e1188ac..96f4e1953f 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 46d7a9f546..089b5d578b 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/dist_ac.beam b/bootstrap/lib/kernel/ebin/dist_ac.beam
index 3060733116..59c75602ec 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 d823f8d5c6..167a70e99d 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 52d638fb32..d88224b5d0 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 81daa5376b..c83b5e393c 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_epmd.beam b/bootstrap/lib/kernel/ebin/erl_epmd.beam
index 9ba74e3303..09746d0403 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/error_handler.beam b/bootstrap/lib/kernel/ebin/error_handler.beam
index e97e1d214f..5a17c845eb 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/erts_debug.beam b/bootstrap/lib/kernel/ebin/erts_debug.beam
index 26288e0633..9108d7e6d5 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 0f11da59e1..2504c16024 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 93e19d9463..ce14722f4c 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 37e598a10f..70bdb58805 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 f66b4635a2..a55e9090a5 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/global.beam b/bootstrap/lib/kernel/ebin/global.beam
index b16334d8a2..20053eb877 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 6e9d6e8dfd..00d03a24f5 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 8270772543..fe18f8f49a 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 8e75aaef55..b72a13dbc7 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 5d5017225d..9d381acaff 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/inet.beam b/bootstrap/lib/kernel/ebin/inet.beam
index a8983e79c1..c712be3bdc 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_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
index c83a3246eb..c2dac7dee1 100644
--- a/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
+++ b/bootstrap/lib/kernel/ebin/inet6_tcp_dist.beam
Binary files differ
diff --git a/bootstrap/lib/kernel/ebin/inet_config.beam b/bootstrap/lib/kernel/ebin/inet_config.beam
index ad3f46010e..edc1e2f6fb 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 3096737c76..2bba1e88c9 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 59e8936722..cfd46c29da 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 22ee6ebfea..0b901a8f27 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_parse.beam b/bootstrap/lib/kernel/ebin/inet_parse.beam
index 926f21e99c..914397158a 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 3b6f72aaa0..0167a10b36 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_tcp_dist.beam b/bootstrap/lib/kernel/ebin/inet_tcp_dist.beam
index 07f6ad2521..6c98977be5 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 2ac9537087..7bd4848f07 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.beam b/bootstrap/lib/kernel/ebin/kernel.beam
index 3eea9dda68..471ab154e8 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 fa245b95c4..da5fa04de5 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_adm.beam b/bootstrap/lib/kernel/ebin/net_adm.beam
index 02b6c8b486..21d54cac85 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 50b4c7ac4c..562ee24678 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 4a4051d0c1..4b3bcf80dd 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 710fc55908..cbe6bc6590 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 38870b0f43..b14425b01c 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 f9488df846..402c7ea2d3 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 2a585c94b3..5fe7a7fffe 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/standard_error.beam b/bootstrap/lib/kernel/ebin/standard_error.beam
index 32554b1b73..62ab951bff 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 07a86f04c2..76e9973a93 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 3feffb9332..ddb0442f28 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/wrap_log_reader.beam b/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
index cdb87c3fd5..9f648c9a42 100644
--- a/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
+++ b/bootstrap/lib/kernel/ebin/wrap_log_reader.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/array.beam b/bootstrap/lib/stdlib/ebin/array.beam
index a3049ae953..1c26f19403 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 101ffc3904..d48d8d6f58 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 58123d66be..e7ba44d542 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/binary.beam b/bootstrap/lib/stdlib/ebin/binary.beam
new file mode 100644
index 0000000000..5180c122d2
--- /dev/null
+++ b/bootstrap/lib/stdlib/ebin/binary.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/c.beam b/bootstrap/lib/stdlib/ebin/c.beam
index e5fe08f44f..099bb5ad90 100644
--- a/bootstrap/lib/stdlib/ebin/c.beam
+++ b/bootstrap/lib/stdlib/ebin/c.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets.beam b/bootstrap/lib/stdlib/ebin/dets.beam
index 8b637ab064..ccd277b7ad 100644
--- a/bootstrap/lib/stdlib/ebin/dets.beam
+++ b/bootstrap/lib/stdlib/ebin/dets.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/dets_utils.beam b/bootstrap/lib/stdlib/ebin/dets_utils.beam
index 36d38c4e9a..b0c3e351d2 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 6537f0e44d..f48768ca53 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 2a247effc1..0694437929 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 3d0b4194b6..ebf01cb9b5 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 41043bf729..38195e8957 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 e0c15a218a..ce329ab2ab 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 fe51f7f417..9fc93d042c 100644
--- a/bootstrap/lib/stdlib/ebin/edlin.beam
+++ b/bootstrap/lib/stdlib/ebin/edlin.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/epp.beam b/bootstrap/lib/stdlib/ebin/epp.beam
index cb5e65c681..8059231d6e 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 7b1f8bb764..d338fe3778 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 cc4ef260d0..3f0cb585e8 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 dfd10fb4bf..cac3a46319 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 2a2ec9b4e1..983fe23879 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 1609ae4997..588f761199 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 21ec2e638f..6862410a3a 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 b1ab1c2d10..426bd23e36 100644
--- a/bootstrap/lib/stdlib/ebin/erl_parse.beam
+++ b/bootstrap/lib/stdlib/ebin/erl_parse.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/erl_pp.beam b/bootstrap/lib/stdlib/ebin/erl_pp.beam
index 161db6cef0..2b6f0a5bd6 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 73f9a4ac97..cffdda03ae 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 40d41d0202..369e5a8c6d 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 ae5a7020ea..13a91def18 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 6065cfa8f1..50dd448b1b 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 3c4b3f4eb6..15f1cb8354 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 17ea23e03b..bcb1b9684c 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 de2d528f2e..1db24ccfc9 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 f03cd21072..c27d4e141f 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 e03b753c09..8a59a62379 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 f419480f6e..4cdb6064d2 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 1ce3e0bd83..1928430e56 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 c462bee0c1..7bebf1a54e 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 bf09b84de6..3ad4d282f0 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 662d4af25c..264071fe5f 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 d5d027ce1e..73df87a7ef 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 5c2c569016..3b066ada0b 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 a9f24817b3..36c276166c 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 af10b8d0e9..c0af612d77 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 16907bb3aa..25f8f7b37a 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_pretty.beam b/bootstrap/lib/stdlib/ebin/io_lib_pretty.beam
index 6b8b7a3267..9a8b68c6e0 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 d7e591ed35..fb08310f36 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 ef6dcfb6ea..153d6fb2ee 100644
--- a/bootstrap/lib/stdlib/ebin/lists.beam
+++ b/bootstrap/lib/stdlib/ebin/lists.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/ms_transform.beam b/bootstrap/lib/stdlib/ebin/ms_transform.beam
index 0dc991553b..918c2537ea 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/otp_internal.beam b/bootstrap/lib/stdlib/ebin/otp_internal.beam
index 974377cdd4..cac4a97ae0 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 aadf03ca28..026d102a75 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 35c2da9051..74377d404b 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 c366aafadf..f6c7a4f748 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 378392c791..bed96c6b1a 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 27dd5d5be0..2e05a4c546 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 10349ebd1a..92b1bc8bee 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/re.beam b/bootstrap/lib/stdlib/ebin/re.beam
index 06c02fc10c..fb8888ad58 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 f45899702c..d021c5779b 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 b8ce3ebe89..9be4e8ab5b 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 a537d0936e..737223aaf8 100644
--- a/bootstrap/lib/stdlib/ebin/shell.beam
+++ b/bootstrap/lib/stdlib/ebin/shell.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/sofs.beam b/bootstrap/lib/stdlib/ebin/sofs.beam
index d8e984f217..51af30d7e8 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 b7cb765910..880e85627e 100644
--- a/bootstrap/lib/stdlib/ebin/stdlib.app
+++ b/bootstrap/lib/stdlib/ebin/stdlib.app
@@ -23,6 +23,7 @@
{modules, [array,
base64,
beam_lib,
+ binary,
c,
calendar,
dets,
diff --git a/bootstrap/lib/stdlib/ebin/supervisor.beam b/bootstrap/lib/stdlib/ebin/supervisor.beam
index 0526384a20..9cbf8912fe 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/sys.beam b/bootstrap/lib/stdlib/ebin/sys.beam
index 5a75152833..e08ec9e70d 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 9d9d42f96d..a20cc97935 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 66d6991283..4ca769b9a2 100644
--- a/bootstrap/lib/stdlib/ebin/unicode.beam
+++ b/bootstrap/lib/stdlib/ebin/unicode.beam
Binary files differ
diff --git a/bootstrap/lib/stdlib/ebin/zip.beam b/bootstrap/lib/stdlib/ebin/zip.beam
index f0df604d79..6c5b31cd1f 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 9afbfb6482..46456b51c5 100644
--- a/bootstrap/lib/stdlib/egen/erl_parse.erl
+++ b/bootstrap/lib/stdlib/egen/erl_parse.erl
@@ -1,6 +1,6 @@
-module(erl_parse).
-export([parse/1, parse_and_scan/1, format_error/1]).
--file("erl_parse.yrl", 490).
+-file("erl_parse.yrl", 502).
-export([parse_form/1,parse_exprs/1,parse_term/1]).
-export([normalise/1,abstract/1,tokens/1,tokens/2]).
@@ -16,8 +16,8 @@
%% mkop(Op, Arg) -> {op,Line,Op,Arg}.
%% mkop(Left, Op, Right) -> {op,Line,Op,Left,Right}.
--define(mkop2(L, OpPos, R),
- begin
+-define(mkop2(L, OpPos, R),
+ begin
{Op,Pos} = OpPos,
{op,Pos,Op,L,R}
end).
@@ -35,6 +35,8 @@
%% These really suck and are only here until Calle gets multiple
%% entry points working.
+parse_form([{'-',L1},{atom,L2,spec}|Tokens]) ->
+ parse([{'-',L1},{'spec',L2}|Tokens]);
parse_form(Tokens) ->
parse(Tokens).
@@ -61,7 +63,7 @@ parse_term(Tokens) ->
-type attributes() :: 'export' | 'file' | 'import' | 'module'
| 'opaque' | 'record' | 'type'.
-build_typed_attribute({atom,La,record},
+build_typed_attribute({atom,La,record},
{typed_record, {atom,_Ln,RecordName}, RecTuple}) ->
{attribute,La,record,{RecordName,record_tuple(RecTuple)}};
build_typed_attribute({atom,La,Attr},
@@ -84,7 +86,7 @@ build_typed_attribute({atom,La,Attr},_) ->
build_type_spec({spec,La}, {SpecFun, TypeSpecs}) ->
NewSpecFun =
case SpecFun of
- {atom, _, Fun} ->
+ {atom, _, Fun} ->
{Fun, find_arity_from_specs(TypeSpecs)};
{{atom,_, Mod}, {atom,_, Fun}} ->
{Mod,Fun,find_arity_from_specs(TypeSpecs)};
@@ -107,11 +109,20 @@ find_arity_from_specs([Spec|_]) ->
{type, _, 'fun', [{type, _, product, Args},_]} = Fun,
length(Args).
+build_def(LHS, Types) ->
+ IsSubType = {atom, ?line(LHS), is_subtype},
+ {type, ?line(LHS), constraint, [IsSubType, [LHS, Types]]}.
+
lift_unions(T1, {type, _La, union, List}) ->
{type, ?line(T1), union, [T1|List]};
lift_unions(T1, T2) ->
{type, ?line(T1), union, [T1, T2]}.
+skip_paren({paren_type,_L,[Type]}) ->
+ skip_paren(Type);
+skip_paren(Type) ->
+ Type.
+
build_gen_type({atom, La, tuple}) ->
{type, La, tuple, any};
build_gen_type({atom, La, Name}) ->
@@ -120,7 +131,7 @@ build_gen_type({atom, La, Name}) ->
build_bin_type([{var, _, '_'}|Left], Int) ->
build_bin_type(Left, Int);
build_bin_type([], Int) ->
- Int;
+ skip_paren(Int);
build_bin_type([{var, La, _}|_], _) ->
ret_err(La, "Bad binary type").
@@ -218,7 +229,7 @@ attribute_farity(Other) -> Other.
attribute_farity_list(Args) ->
[attribute_farity(A) || A <- Args].
-
+
-spec error_bad_decl(integer(), attributes()) -> no_return().
error_bad_decl(L, S) ->
@@ -241,17 +252,17 @@ record_fields([{match,_Lm,{atom,La,A},Expr}|Fields]) ->
[{record_field,La,{atom,La,A},Expr}|record_fields(Fields)];
record_fields([{typed,Expr,TypeInfo}|Fields]) ->
[Field] = record_fields([Expr]),
- TypeInfo1 =
+ TypeInfo1 =
case Expr of
{match, _, _, _} -> TypeInfo; %% If we have an initializer.
- {atom, La, _} ->
+ {atom, La, _} ->
case has_undefined(TypeInfo) of
false ->
lift_unions(abstract(undefined, La), TypeInfo);
true ->
TypeInfo
end
- end,
+ end,
[{typed_record_field,Field,TypeInfo1}|record_fields(Fields)];
record_fields([Other|_Fields]) ->
ret_err(?line(Other), "bad record field");
@@ -507,7 +518,7 @@ inop_prec('#') -> {800,700,800};
inop_prec(':') -> {900,800,900};
inop_prec('.') -> {900,900,1000}.
--type pre_op() :: 'catch' | '+' | '-' | 'bnot' | '#'.
+-type pre_op() :: 'catch' | '+' | '-' | 'bnot' | 'not' | '#'.
-spec preop_prec(pre_op()) -> {0 | 600 | 700, 100 | 700 | 800}.
@@ -545,7 +556,7 @@ get_attribute(L, Name) ->
get_attributes(L) ->
erl_scan:attributes_info(L).
--file("/usr/local/otp/releases/sles10_32_R13B04_patched/lib/parsetools-2.0.2/include/yeccpre.hrl", 0).
+-file("/usr/local/otp/releases/otp_beam_linux_sles10_x64_r13b02_patched/lib/parsetools-2.0/include/yeccpre.hrl", 0).
%%
%% %CopyrightBegin%
%%
@@ -568,32 +579,33 @@ get_attributes(L) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% 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({function() | {atom(), atom()}, [_]} | {atom(), atom(), [_]}) ->
- yecc_ret().
+-spec(parse_and_scan/1 ::
+ ({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(any()) -> [char() | list()].
+-spec(format_error/1 :: (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(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/2 :: (integer(), any()) -> no_return()).
return_error(Line, Message) ->
throw({error, {Line, ?MODULE, Message}}).
@@ -632,7 +644,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} ->
@@ -665,7 +677,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) ->
@@ -726,7 +738,7 @@ yecctoken2string(Other) ->
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 729).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 741).
yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr);
@@ -746,36 +758,36 @@ yeccpars2(0=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_7(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(8=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_8(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(9=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(9=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(10=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(11=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(12=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_12(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(11=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_11(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(12=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_12(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(13=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_13(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(14=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_14(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(14=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_14(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(15=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_15(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(16=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_16(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(17=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_17(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(18=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(18=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(19=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_16(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_19(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(20=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_20(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(21=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_21(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(22=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_22(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(24=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_24(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(25=S, Cat, Ss, Stack, T, Ts, Tzr) ->
@@ -790,44 +802,44 @@ yeccpars2(23=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_29(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(30=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_30(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(31=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(32=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(33=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_33(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_34(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(36=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(37=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_37(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(38=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_38(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(39=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_39(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(40=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_40(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(31=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_31(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(32=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(33=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_33(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(34=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_34(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(35=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_35(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(36=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(37=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_37(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(38=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_38(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(39=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_39(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(40=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_40(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(41=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_41(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(42=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_42(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(43=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_43(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(42=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_42(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(43=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_43(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(44=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_44(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(45=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(45=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(46=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_46(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(47=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_47(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(48=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_48(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(49=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_49(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(48=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_48(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(49=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_49(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(50=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_50(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(51=S, Cat, Ss, Stack, T, Ts, Tzr) ->
@@ -835,21 +847,21 @@ yeccpars2(51=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2(52=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_52(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(53=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_53(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(54=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_54(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(55=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_55(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(56=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(57=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(57=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_57(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(58=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_58(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(59=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_59(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(59=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_59(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(60=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_60(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(61=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_61(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(62=S, Cat, Ss, Stack, T, Ts, Tzr) ->
@@ -861,503 +873,503 @@ yeccpars2(64=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2(65=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_65(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(66=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_66(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(67=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_67(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(68=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(69=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_69(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(67=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_67(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(68=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(69=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_69(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(70=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_70(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(71=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_71(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(72=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_72(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(73=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_73(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(72=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_72(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(73=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_73(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(74=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_74(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(75=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_75(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(76=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_76(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(77=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_77(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(77=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_77(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(78=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_78(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(79=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(79=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_79(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(80=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_80(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(81=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_81(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(82=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_82(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(83=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(81=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_81(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(82=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_82(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(83=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(84=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(85=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_85(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(86=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_86(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(87=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_87(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(88=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_88(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(89=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_89(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(90=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_90(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(89=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_89(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(90=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(91=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_91(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(92=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_92(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(93=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_93(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(94=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(95=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_95(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(93=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_93(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(94=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_94(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(95=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_95(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(96=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(97=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_97(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(98=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_98(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(99=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_99(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(100=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(101=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_101(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(102=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_102(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_96(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(97=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(98=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_98(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(99=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(100=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_100(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(101=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(102=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_102(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(103=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_103(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(104=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_104(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(105=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_105(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(104=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_104(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(105=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(106=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_106(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(107=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_107(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(108=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_108(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_75(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(108=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_108(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(109=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_109(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(110=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_110(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(111=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_111(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(112=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_112(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(113=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_113(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(114=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_114(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(115=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(115=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_115(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(116=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_116(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(117=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_44(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(118=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_118(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(119=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(120=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_120(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(121=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_121(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(122=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_122(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(123=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(119=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_119(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(120=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_120(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(121=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(122=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_122(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(123=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(124=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_124(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(125=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_125(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(126=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(127=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_127(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(128=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_16(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(129=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_129(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(130=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_130(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(131=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_131(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(132=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(126=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_126(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(127=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(128=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_128(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(129=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(130=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_130(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(131=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_131(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(132=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_132(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(133=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_133(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(134=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_134(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(135=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_135(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(135=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_135(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(136=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_136(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(137=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_137(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(137=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_137(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(138=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_138(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(139=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_139(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(140=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_140(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(141=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_141(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(140=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_140(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(141=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_141(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(142=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_142(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(143=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_143(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(144=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_144(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(145=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_145(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(146=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_146(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(146=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(147=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_147(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(148=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_148(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(148=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_148(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(149=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_149(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(150=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_150(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(151=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_151(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(152=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_152(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(153=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_153(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(154=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_154(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(155=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_155(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(156=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_156(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(157=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_157(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(158=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_158(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(152=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_152(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(153=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_153(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(154=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_154(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(155=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_155(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(156=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_156(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(157=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_157(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(158=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_158(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(159=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_159(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(160=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_160(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(161=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_161(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(161=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(162=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_162(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(163=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_163(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(163=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_163(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(164=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_164(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(165=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_165(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(166=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_166(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(166=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(167=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_167(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(168=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_168(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(168=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_168(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(169=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_169(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(170=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_170(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(170=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_170(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(171=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_171(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(172=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(173=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_172(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(173=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(174=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_174(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(175=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_175(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(176=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(177=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_177(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(177=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_177(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(178=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_178(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(179=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(180=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_180(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(181=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(182=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(183=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_183(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(184=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_184(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(185=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_185(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(186=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(179=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_179(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(180=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_180(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(181=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_181(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(182=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_182(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(183=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_183(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(184=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_184(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(185=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_185(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(186=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_186(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(187=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_187(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(188=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_188(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(189=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_189(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(189=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_189(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(190=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_190(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(191=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_191(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(192=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(192=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_192(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(193=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_193(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(194=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_194(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(195=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_195(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(194=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_194(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(195=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_181(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(196=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_196(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(197=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(198=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_198(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(199=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_199(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(200=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_200(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(201=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(202=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_202(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(197=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_197(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(198=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_198(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(199=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_199(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(200=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_200(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(201=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_201(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(202=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_202(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(203=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_203(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(204=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_204(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(205=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_205(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(206=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(207=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_207(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(204=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_204(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(205=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_199(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(206=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_206(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(207=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_207(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(208=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_208(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(209=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_209(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(210=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_210(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(211=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_211(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(212=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(213=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_213(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(214=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_214(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(210=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_210(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(211=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_211(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(212=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_212(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(213=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_213(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(214=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_214(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(215=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(216=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(217=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_217(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(218=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_218(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(216=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_216(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(217=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_217(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(218=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_218(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(219=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(220=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_220(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_219(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(220=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(221=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_221(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(222=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(223=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_223(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(224=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_224(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(224=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_224(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(225=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_225(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(226=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_226(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(227=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_227(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(226=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_226(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(227=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_227(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(228=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_228(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(229=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(230=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(231=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(229=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_229(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(230=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(231=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(232=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_232(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(233=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(234=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_234(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(233=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_233(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(234=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(235=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(236=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_236(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_235(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(236=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(237=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_237(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(238=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_238(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(239=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_207(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(240=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_240(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_239(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(240=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_240(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(241=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_241(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(242=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_242(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(243=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_243(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(243=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_243(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(244=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_244(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(245=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_245(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(245=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_245(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(246=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_246(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(247=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_247(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(248=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_248(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(249=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(250=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(251=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_251(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(249=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(250=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_250(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(251=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_251(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(252=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_252(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(253=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_253(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(254=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_254(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(255=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(256=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_256(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(255=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_255(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(256=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_256(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(257=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_257(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(258=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_258(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(258=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_258(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(259=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_259(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(260=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_260(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(261=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(262=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_262(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(263=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_263(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(264=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_264(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(265=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_265(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(261=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(262=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_262(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(263=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_263(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(264=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_264(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(265=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_265(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(266=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(267=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_267(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(268=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_266(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(267=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_267(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(268=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_268(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(269=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_269(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(270=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(271=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_271(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(270=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_270(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(271=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_271(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(272=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_272(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(273=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_273(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(274=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_274(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(275=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_275(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(276=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_181(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(273=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_273(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(274=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_274(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(275=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_275(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(276=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_276(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(277=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_277(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(278=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(279=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_279(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_278(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(279=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_279(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(280=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_280(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(281=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_281(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(282=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_282(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(283=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_283(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(282=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_282(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(283=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_283(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(284=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_284(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(285=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_285(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(286=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_286(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(287=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_287(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(288=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_288(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(286=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_286(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(287=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_287(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(288=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_288(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(289=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(290=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_290(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(291=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_291(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_289(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(290=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(291=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_291(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(292=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(293=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_293(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(294=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_294(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(295=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_295(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_292(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(293=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_293(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(294=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_294(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(295=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_295(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(296=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_296(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(297=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(298=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_298(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_297(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(298=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_298(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(299=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_299(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(300=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_300(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(301=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_301(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(300=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_300(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(301=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_301(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(302=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(303=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_303(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_302(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(303=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_303(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(304=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_304(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(305=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_305(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(306=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_306(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(305=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_305(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(306=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_295(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(307=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_307(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(308=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_308(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(308=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_308(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(309=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_309(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(310=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(311=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_311(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(312=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_310(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(311=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_311(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(312=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_312(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(313=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_313(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(314=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_314(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(314=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_314(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(315=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_315(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(316=S, Cat, Ss, Stack, T, Ts, Tzr) ->
@@ -1370,6437 +1382,6547 @@ yeccpars2(314=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_319(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(320=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_320(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(321=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_321(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(322=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(321=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_321(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(322=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(323=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_323(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(324=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_324(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(325=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_325(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(325=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_325(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(326=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_326(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(327=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(328=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_328(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_327(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(328=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_328(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(329=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_329(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(330=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_330(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(331=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_317(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(332=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_332(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(333=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_333(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(334=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_334(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(335=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(336=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_336(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(337=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_337(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(330=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_330(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(331=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_331(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(332=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_332(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(333=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_333(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(334=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_334(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(335=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_335(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(336=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_336(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(337=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_337(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(338=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_338(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(339=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_339(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(339=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_339(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(340=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_340(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(341=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(342=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_342(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(343=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_343(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(344=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_344(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_341(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(342=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_342(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(343=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_343(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(344=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(345=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_345(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(346=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_346(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(346=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_346(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(347=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_347(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(348=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(349=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_349(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(350=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_350(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_348(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(349=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_349(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(350=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_350(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(351=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_351(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(352=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_194(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(353=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_353(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_352(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(353=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_353(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(354=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_354(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(355=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_355(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(355=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_355(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(356=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(357=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(358=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_358(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(359=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_359(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_356(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(357=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_357(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(358=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_358(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(359=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_359(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(360=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(361=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_361(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(362=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_362(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(363=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_363(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(364=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_364(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_360(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(361=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_361(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(362=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_362(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(363=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_363(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(364=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_364(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(365=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_365(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(366=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_366(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(367=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_367(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(368=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(366=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_366(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(367=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_367(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(368=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_368(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(369=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_369(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(370=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_370(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(370=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(371=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_371(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(372=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_372(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(372=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_372(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(373=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_373(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(374=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_374(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(374=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_374(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(375=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(376=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_376(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_375(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(376=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_376(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(377=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(378=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_378(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_377(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(378=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_378(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(379=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_379(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(380=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_380(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(381=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_381(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(380=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(381=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_381(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(382=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_382(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(383=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_347(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(384=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_384(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_383(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(384=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_384(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(385=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(386=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(386=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_386(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(387=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_387(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(388=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_388(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(388=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_388(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(389=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(390=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_390(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(391=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(392=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_392(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_389(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(390=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(391=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_391(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(392=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_392(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(393=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_393(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(394=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_394(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(395=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_395(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(395=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_395(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(396=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_396(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(397=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_397(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(397=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_397(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(398=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_398(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(399=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_399(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(400=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_400(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(400=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_400(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(401=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_401(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_334(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(402=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_402(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(403=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(404=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(405=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_405(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(406=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_406(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(407=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_407(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(408=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_408(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2_334(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(404=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_334(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(405=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_405(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(406=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_406(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(407=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_334(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(408=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_408(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(409=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_409(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(410=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_410(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(411=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_411(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(410=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_410(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(411=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_411(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(412=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_412(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(413=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_413(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(414=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_414(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(415=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_415(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(416=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(417=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_417(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(416=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(417=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_417(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(418=S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_418(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(419=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_419(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(420=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_420(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_409(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(420=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_420(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(421=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_421(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(422=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_422(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(423=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_423(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_295(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(422=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_422(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(423=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_423(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(424=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_424(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(425=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_425(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(426=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(427=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_317(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(428=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_428(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(426=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_426(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(427=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_427(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(428=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(429=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_429(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(430=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(431=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_431(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(432=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_432(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(433=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(430=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_430(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(431=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_431(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(432=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(433=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_433(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(434=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_434(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(435=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_435(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(436=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_436(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(436=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(437=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_437(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(438=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_438(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(439=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_439(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(440=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_440(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(440=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(441=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(442=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_442(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(443=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_443(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(443=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_443(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(444=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_444(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(445=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(445=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_445(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(446=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_446(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(447=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(448=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_448(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(449=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_215(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(447=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_447(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(448=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_448(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(449=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_449(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(450=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_450(S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccpars2(451=S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(452=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_452(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(453=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_9(S, Cat, Ss, Stack, T, Ts, Tzr);
-%% yeccpars2(454=S, Cat, Ss, Stack, T, Ts, Tzr) ->
-%% yeccpars2_454(S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_431(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(451=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_451(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(452=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_452(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(453=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_453(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(454=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_454(S, Cat, Ss, Stack, T, Ts, Tzr);
%% yeccpars2(455=S, Cat, Ss, Stack, T, Ts, Tzr) ->
%% yeccpars2_455(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(456=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(457=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_457(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(458=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_83(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(459=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_459(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(460=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_460(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(461=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_461(S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccpars2(462=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_10(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(463=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_463(S, Cat, Ss, Stack, T, Ts, Tzr);
+%% yeccpars2(464=S, Cat, Ss, Stack, T, Ts, Tzr) ->
+%% yeccpars2_464(S, Cat, Ss, Stack, T, Ts, Tzr);
yeccpars2(Other, _, _, _, _, _, _) ->
erlang:error({yecc_bug,"1.3",{missing_state_in_action_table, Other}}).
yeccpars2_0(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr);
-yeccpars2_0(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 9, Ss, Stack, T, Ts, Tzr);
+yeccpars2_0(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 10, Ss, Stack, T, Ts, Tzr).
yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_1_(Stack),
yeccgoto_rule(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_2(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 451, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 460, Ss, Stack, T, Ts, Tzr);
yeccpars2_2(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_2_(Stack),
yeccgoto_rule_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_3(S, dot, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 450, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 459, Ss, Stack, T, Ts, Tzr).
yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_4_(Stack),
yeccgoto_function(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_5(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 445, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 454, Ss, Stack, T, Ts, Tzr);
yeccpars2_5(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_5_(Stack),
yeccgoto_function_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_6(S, dot, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 444, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 453, Ss, Stack, T, Ts, Tzr).
yeccpars2_7(_S, '$end', _Ss, Stack, _T, _Ts, _Tzr) ->
{ok, hd(Stack)}.
yeccpars2_8(S, dot, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 443, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 452, Ss, Stack, T, Ts, Tzr).
-yeccpars2_9(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 285, Ss, Stack, T, Ts, Tzr).
+yeccpars2_9(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 292, Ss, Stack, T, Ts, Tzr);
+yeccpars2_9(S, spec, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 293, Ss, Stack, T, Ts, Tzr).
-yeccpars2_10(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr);
-yeccpars2_10(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 14, Ss, Stack, T, Ts, Tzr).
+yeccpars2_10(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr).
+yeccpars2_11(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
yeccpars2_11(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_atom1(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_11_(Stack),
+ yeccpars2_287(287, Cat, [11 | Ss], NewStack, T, Ts, Tzr).
yeccpars2_12(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
NewStack = yeccpars2_12_(Stack),
- yeccgoto_atom1(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_clause_args(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_13(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 173, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_13(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 46, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_13(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
yeccpars2_13(S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_cont_13(S, '<<', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 177, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 50, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, '[', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 51, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, 'begin', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 179, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, 'case', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 181, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, char, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 183, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 57, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, float, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 184, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 58, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, 'fun', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 185, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 59, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, 'if', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 186, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 60, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 187, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 61, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, 'query', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 189, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, 'receive', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 190, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 64, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, string, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 191, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr);
yeccpars2_cont_13(S, 'try', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 192, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 66, Ss, Stack, T, Ts, Tzr).
-yeccpars2_14(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 18, Ss, Stack, T, Ts, Tzr);
-yeccpars2_14(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_15_(Stack),
- yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_16(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 23, Ss, Stack, T, Ts, Tzr).
+yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_17(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 131, Ss, Stack, T, Ts, Tzr);
-yeccpars2_17(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 132, Ss, Stack, T, Ts, Tzr);
+yeccpars2_17(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 282, Ss, Stack, T, Ts, Tzr);
yeccpars2_17(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_spec_fun(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr_700(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_18(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_18(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr).
+yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_19: see yeccpars2_16
+yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_20(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 130, Ss, Stack, T, Ts, Tzr).
+yeccpars2_20(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_20(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_20(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_20(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_20(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_20(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_20(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_21(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 128, Ss, Stack, T, Ts, Tzr);
yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_21_(Stack),
- yeccgoto_type_sigs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_22(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 119, Ss, Stack, T, Ts, Tzr);
yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_type_sig(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_23(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 33, Ss, Stack, T, Ts, Tzr);
-yeccpars2_23(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_23(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_23(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_23(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_23(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr);
-yeccpars2_23(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_cont_23(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 31, Ss, Stack, T, Ts, Tzr);
-yeccpars2_cont_23(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 32, Ss, Stack, T, Ts, Tzr);
-yeccpars2_cont_23(S, '<<', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 35, Ss, Stack, T, Ts, Tzr);
-yeccpars2_cont_23(S, '[', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 36, Ss, Stack, T, Ts, Tzr);
-yeccpars2_cont_23(S, 'fun', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 37, Ss, Stack, T, Ts, Tzr);
-yeccpars2_cont_23(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 40, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_24(S, '|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 117, Ss, Stack, T, Ts, Tzr);
yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_top_type_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr_700(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_25(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 114, Ss, Stack, T, Ts, Tzr).
+yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_top_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_26(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 280, Ss, Stack, T, Ts, Tzr).
-yeccpars2_27(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 112, Ss, Stack, T, Ts, Tzr);
+yeccpars2_27(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 275, Ss, Stack, T, Ts, Tzr);
yeccpars2_27(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_27_(Stack),
- yeccgoto_top_types(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_900(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_28(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 109, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 271, Ss, Stack, T, Ts, Tzr);
+yeccpars2_28(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 272, Ss, Stack, T, Ts, Tzr);
yeccpars2_28(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr_800(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_29(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr);
yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr_700(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_30(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 99, Ss, Stack, T, Ts, Tzr);
-yeccpars2_30(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 100, Ss, Stack, T, Ts, Tzr);
yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr_600(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_31: see yeccpars2_18
-
-yeccpars2_32(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_32(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_32(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_32(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_32(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr);
-yeccpars2_32(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_33(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_34(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 83, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_35(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 69, Ss, Stack, T, Ts, Tzr);
-yeccpars2_35(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 70, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_36(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_36(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 60, Ss, Stack, T, Ts, Tzr);
-yeccpars2_36(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_36(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_36(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_36(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr);
-yeccpars2_36(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_37(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr).
+yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_500(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_32(S, '*', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr);
+yeccpars2_32(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 263, Ss, Stack, T, Ts, Tzr);
+yeccpars2_32(S, 'and', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr);
+yeccpars2_32(S, 'band', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 265, Ss, Stack, T, Ts, Tzr);
+yeccpars2_32(S, 'div', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr);
+yeccpars2_32(S, 'rem', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 267, Ss, Stack, T, Ts, Tzr);
+yeccpars2_32(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_400(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_33(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 250, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, '++', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 251, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 252, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, '--', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 253, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, 'bor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, 'bsl', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 255, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, 'bsr', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 256, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, 'bxor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 257, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, 'or', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 258, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(S, 'xor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 259, Ss, Stack, T, Ts, Tzr);
+yeccpars2_33(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_300(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_34(S, '/=', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 239, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(S, '<', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 240, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(S, '=/=', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 241, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(S, '=:=', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 242, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(S, '=<', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 243, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(S, '==', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 244, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(S, '>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 245, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(S, '>=', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 246, Ss, Stack, T, Ts, Tzr);
+yeccpars2_34(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_200(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_35(S, 'andalso', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 236, Ss, Stack, T, Ts, Tzr);
+yeccpars2_35(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_160(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_36(S, 'orelse', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 234, Ss, Stack, T, Ts, Tzr);
+yeccpars2_36(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_150(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_37(S, '!', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 230, Ss, Stack, T, Ts, Tzr);
+yeccpars2_37(S, '=', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 231, Ss, Stack, T, Ts, Tzr);
+yeccpars2_37(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_int_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_39(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_39(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 228, Ss, Stack, T, Ts, Tzr);
yeccpars2_39(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_39_(Stack),
+ yeccgoto_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_40(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_40(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_40(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_40(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_40(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr);
-yeccpars2_40(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 42, Ss, Stack, T, Ts, Tzr);
-yeccpars2_40(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_41(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 43, Ss, Stack, T, Ts, Tzr).
+yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_42_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_43_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_44(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
yeccpars2_44(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_44(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_44(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_44(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 46, Ss, Stack, T, Ts, Tzr);
-yeccpars2_44(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 211, Ss, Stack, T, Ts, Tzr).
-yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_45_(Stack),
- yeccgoto_top_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_45(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_45(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_46(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_46_(Stack),
+ yeccgoto_argument_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_47(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 50, Ss, Stack, T, Ts, Tzr);
-yeccpars2_47(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 51, Ss, Stack, T, Ts, Tzr).
+yeccpars2_47(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_48(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 58, Ss, Stack, T, Ts, Tzr).
+yeccpars2_48(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_49(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_fun_type_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_49(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 208, Ss, Stack, T, Ts, Tzr).
-yeccpars2_50(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 33, Ss, Stack, T, Ts, Tzr);
+yeccpars2_50(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_50(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
yeccpars2_50(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_50(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_50(S, '>>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 187, Ss, Stack, T, Ts, Tzr);
yeccpars2_50(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_50(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_50(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_50(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_50(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
yeccpars2_50(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_50(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
yeccpars2_50(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_51(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_51_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_51(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, ']', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_51(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_52(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 53, Ss, Stack, T, Ts, Tzr).
+yeccpars2_52(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_53(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_53: see yeccpars2_45
-yeccpars2_54(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 55, Ss, Stack, T, Ts, Tzr).
+yeccpars2_54(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_55(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_55: see yeccpars2_45
-%% yeccpars2_56: see yeccpars2_32
+%% yeccpars2_56: see yeccpars2_45
yeccpars2_57(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_57_(Stack),
- yeccgoto_fun_type_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_58(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
- NewStack = yeccpars2_58_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_59(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 61, Ss, Stack, T, Ts, Tzr);
-yeccpars2_59(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr).
+yeccpars2_59(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 13, Ss, Stack, T, Ts, Tzr);
+yeccpars2_59(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 152, Ss, Stack, T, Ts, Tzr).
-yeccpars2_60(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_60_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_60: see yeccpars2_45
-yeccpars2_61(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 63, Ss, Stack, T, Ts, Tzr).
+yeccpars2_61(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_62(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_62_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_63(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 64, Ss, Stack, T, Ts, Tzr).
+yeccpars2_63(S, '[', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 127, Ss, Stack, T, Ts, Tzr).
+yeccpars2_64(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
yeccpars2_64(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_65(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 66, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, 'after', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 117, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_64(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_66(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_66_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_65(S, string, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 65, Ss, Stack, T, Ts, Tzr);
+yeccpars2_65(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_strings(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_67(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 82, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_66: see yeccpars2_45
-yeccpars2_68(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 76, Ss, Stack, T, Ts, Tzr);
-yeccpars2_68(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 77, Ss, Stack, T, Ts, Tzr).
+yeccpars2_67(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_69(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_69_(Stack),
- yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_68(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 70, Ss, Stack, T, Ts, Tzr);
+yeccpars2_68(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_70(S, ':', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_69(S, '}', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 71, Ss, Stack, T, Ts, Tzr).
-yeccpars2_71(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 72, Ss, Stack, T, Ts, Tzr);
-yeccpars2_71(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 73, Ss, Stack, T, Ts, Tzr).
+yeccpars2_70(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_70_(Stack),
+ yeccgoto_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_72(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_71(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_72_(Stack),
- yeccgoto_bin_base_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_71_(Stack),
+ yeccgoto_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_73(S, '*', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 74, Ss, Stack, T, Ts, Tzr).
+yeccpars2_72(S, 'of', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 76, Ss, Stack, T, Ts, Tzr);
+yeccpars2_72(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_78(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_74(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 75, Ss, Stack, T, Ts, Tzr).
+yeccpars2_73(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_73_(Stack),
+ yeccgoto_try_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_75(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_75_(Stack),
- yeccgoto_bin_unit_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_74: see yeccpars2_45
+
+yeccpars2_75(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 95, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 96, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_75(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_76(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 79, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_76: see yeccpars2_45
+yeccpars2_77(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
yeccpars2_77(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
NewStack = yeccpars2_77_(Stack),
- yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccpars2_83(83, Cat, [77 | Ss], NewStack, T, Ts, Tzr).
-yeccpars2_78(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 81, Ss, Stack, T, Ts, Tzr).
+yeccpars2_78(S, 'after', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 74, Ss, Stack, T, Ts, Tzr);
+yeccpars2_78(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 75, Ss, Stack, T, Ts, Tzr).
-yeccpars2_79(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 80, Ss, Stack, T, Ts, Tzr).
+yeccpars2_79(S, ';', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 80, Ss, Stack, T, Ts, Tzr);
+yeccpars2_79(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_79_(Stack),
+ yeccgoto_cr_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_80(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 73, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_80: see yeccpars2_45
yeccpars2_81(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_81_(Stack),
- yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_cr_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_82(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_82_(Stack),
- yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_try_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_83(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_83_(Stack),
- yeccgoto_int_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_83(S, '->', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 90, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_84: see yeccpars2_32
+%% yeccpars2_84: see yeccpars2_45
yeccpars2_85(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
+ [_|Nss] = Ss,
NewStack = yeccpars2_85_(Stack),
- yeccgoto_fun_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_clause_guard(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_86(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 87, Ss, Stack, T, Ts, Tzr).
+yeccpars2_86(S, ';', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 87, Ss, Stack, T, Ts, Tzr);
+yeccpars2_86(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_86_(Stack),
+ yeccgoto_guard(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_87(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_87_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_87: see yeccpars2_45
-yeccpars2_88(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 89, Ss, Stack, T, Ts, Tzr).
+yeccpars2_88(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_88_(Stack),
+ yeccgoto_guard(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_89(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 93, Ss, Stack, T, Ts, Tzr);
-yeccpars2_89(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_89(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_89_(Stack),
+ yeccgoto_cr_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_90(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 98, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_90: see yeccpars2_45
-yeccpars2_91(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 96, Ss, Stack, T, Ts, Tzr);
yeccpars2_91(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
NewStack = yeccpars2_91_(Stack),
- yeccgoto_field_types(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_clause_body(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_92(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 94, Ss, Stack, T, Ts, Tzr).
+yeccpars2_92(S, 'after', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 109, Ss, Stack, T, Ts, Tzr);
+yeccpars2_92(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 110, Ss, Stack, T, Ts, Tzr).
+yeccpars2_93(S, ';', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
yeccpars2_93(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
NewStack = yeccpars2_93_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_try_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-%% yeccpars2_94: see yeccpars2_32
+yeccpars2_94(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
+yeccpars2_94(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_94_(Stack),
+ yeccpars2_83(105, Cat, [94 | Ss], NewStack, T, Ts, Tzr).
+yeccpars2_95(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 101, Ss, Stack, T, Ts, Tzr);
yeccpars2_95(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_95_(Stack),
- yeccgoto_field_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_96: see yeccpars2_18
+yeccpars2_96(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 97, Ss, Stack, T, Ts, Tzr);
+yeccpars2_96(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_97(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_97_(Stack),
- yeccgoto_field_types(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_97: see yeccpars2_45
+yeccpars2_98(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
yeccpars2_98(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_98_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccpars2_83(99, Cat, [98 | Ss], NewStack, T, Ts, Tzr).
-yeccpars2_99(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 107, Ss, Stack, T, Ts, Tzr);
-yeccpars2_99(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_99(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_99(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_99(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_99(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr);
-yeccpars2_99(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-%% yeccpars2_100: see yeccpars2_18
-
-yeccpars2_101(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 102, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_102(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 104, Ss, Stack, T, Ts, Tzr);
-yeccpars2_102(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_102(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_102(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr);
-yeccpars2_102(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_102(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 39, Ss, Stack, T, Ts, Tzr);
-yeccpars2_102(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_23(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_103(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 105, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_99: see yeccpars2_83
+
+yeccpars2_100(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_100_(Stack),
+ yeccgoto_try_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+%% yeccpars2_101: see yeccpars2_45
+
+yeccpars2_102(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
+yeccpars2_102(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_102_(Stack),
+ yeccpars2_83(103, Cat, [102 | Ss], NewStack, T, Ts, Tzr).
+
+%% yeccpars2_103: see yeccpars2_83
yeccpars2_104(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_104_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-yeccpars2_105(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_105_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_try_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_106(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 108, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_105: see yeccpars2_83
-yeccpars2_107(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_106(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_107_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_106_(Stack),
+ yeccgoto_try_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+%% yeccpars2_107: see yeccpars2_75
yeccpars2_108(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_108_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_try_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_109(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 110, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_109: see yeccpars2_45
-yeccpars2_110(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 34, Ss, Stack, T, Ts, Tzr);
-yeccpars2_110(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 38, Ss, Stack, T, Ts, Tzr).
+yeccpars2_110(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_110_(Stack),
+ yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_111(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
- NewStack = yeccpars2_111_(Stack),
- yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_111(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 112, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_112(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_112_(Stack),
+ yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_112: see yeccpars2_32
+yeccpars2_113(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 114, Ss, Stack, T, Ts, Tzr).
-yeccpars2_113(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_114(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_113_(Stack),
- yeccgoto_top_types(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-yeccpars2_114(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 115, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_114_(Stack),
+ yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_115: see yeccpars2_32
+yeccpars2_115(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_115_(Stack),
+ yeccgoto_strings(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_116(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_116_(Stack),
- yeccgoto_fun_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_116(S, 'after', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 121, Ss, Stack, T, Ts, Tzr);
+yeccpars2_116(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 122, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_117: see yeccpars2_44
+%% yeccpars2_117: see yeccpars2_45
-yeccpars2_118(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_118_(Stack),
- yeccgoto_top_type_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_118: see yeccpars2_83
-%% yeccpars2_119: see yeccpars2_18
+yeccpars2_119(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 120, Ss, Stack, T, Ts, Tzr).
yeccpars2_120(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_120_(Stack),
- yeccgoto_type_sig(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_121(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 126, Ss, Stack, T, Ts, Tzr);
-yeccpars2_121(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_121_(Stack),
- yeccgoto_type_guards(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+%% yeccpars2_121: see yeccpars2_45
-yeccpars2_122(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 123, Ss, Stack, T, Ts, Tzr).
+yeccpars2_122(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_122_(Stack),
+ yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_123: see yeccpars2_32
+%% yeccpars2_123: see yeccpars2_83
-yeccpars2_124(S, ')', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_124(S, 'end', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 125, Ss, Stack, T, Ts, Tzr).
yeccpars2_125(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
+ [_,_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_125_(Stack),
- yeccgoto_type_guard(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_126: see yeccpars2_18
+yeccpars2_126(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 141, Ss, Stack, T, Ts, Tzr).
-yeccpars2_127(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_127_(Stack),
- yeccgoto_type_guards(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_127: see yeccpars2_45
-%% yeccpars2_128: see yeccpars2_16
+yeccpars2_128(S, '||', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 129, Ss, Stack, T, Ts, Tzr).
-yeccpars2_129(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_129_(Stack),
- yeccgoto_type_sigs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_129: see yeccpars2_45
-yeccpars2_130(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
- NewStack = yeccpars2_130_(Stack),
- yeccgoto_type_spec(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_130(S, ']', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 140, Ss, Stack, T, Ts, Tzr).
-yeccpars2_131(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 137, Ss, Stack, T, Ts, Tzr).
+yeccpars2_131(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 138, Ss, Stack, T, Ts, Tzr);
+yeccpars2_131(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_131_(Stack),
+ yeccgoto_lc_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-%% yeccpars2_132: see yeccpars2_18
+yeccpars2_132(S, '<-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 136, Ss, Stack, T, Ts, Tzr);
+yeccpars2_132(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_lc_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_133(S, '/', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_133(S, '<=', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 134, Ss, Stack, T, Ts, Tzr);
yeccpars2_133(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_133_(Stack),
- yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_134(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 135, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_134: see yeccpars2_45
-yeccpars2_135(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 136, Ss, Stack, T, Ts, Tzr).
+yeccpars2_135(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_135_(Stack),
+ yeccgoto_lc_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_136(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_136_(Stack),
- yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_136: see yeccpars2_45
-yeccpars2_137(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 138, Ss, Stack, T, Ts, Tzr).
+yeccpars2_137(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_137_(Stack),
+ yeccgoto_lc_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_138(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
- NewStack = yeccpars2_138_(Stack),
- yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_138: see yeccpars2_45
yeccpars2_139(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_139_(Stack),
- yeccgoto_type_spec(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_lc_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_140(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_140_(Stack),
- yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_list_comprehension(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_141_(Stack),
+ yeccgoto_query_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_142(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 148, Ss, Stack, T, Ts, Tzr).
+yeccpars2_143(S, ';', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 146, Ss, Stack, T, Ts, Tzr);
yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_143_(Stack),
+ yeccgoto_if_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_700(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_144: see yeccpars2_83
yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_145_(Stack),
+ yeccgoto_if_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_146: see yeccpars2_45
-yeccpars2_147(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_147(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_147(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
-yeccpars2_147(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_147(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_147(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_147(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_147(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_147(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_147_(Stack),
+ yeccgoto_if_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_148_(Stack),
+ yeccgoto_if_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_149(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 163, Ss, Stack, T, Ts, Tzr).
+yeccpars2_150(S, ';', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 161, Ss, Stack, T, Ts, Tzr);
yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_150_(Stack),
+ yeccgoto_fun_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_151(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_700(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_151_(Stack),
+ yeccpars2_83(159, Cat, [151 | Ss], NewStack, T, Ts, Tzr).
-yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_152(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 153, Ss, Stack, T, Ts, Tzr);
+yeccpars2_152(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 154, Ss, Stack, T, Ts, Tzr).
-yeccpars2_153(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 430, Ss, Stack, T, Ts, Tzr);
-yeccpars2_153(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_900(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_153(S, integer, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 158, Ss, Stack, T, Ts, Tzr).
-yeccpars2_154(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 426, Ss, Stack, T, Ts, Tzr);
-yeccpars2_154(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 427, Ss, Stack, T, Ts, Tzr);
-yeccpars2_154(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_800(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_154(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 155, Ss, Stack, T, Ts, Tzr).
-yeccpars2_155(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 285, Ss, Stack, T, Ts, Tzr);
-yeccpars2_155(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_700(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_155(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 156, Ss, Stack, T, Ts, Tzr).
-yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_600(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_156(S, integer, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 157, Ss, Stack, T, Ts, Tzr).
yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_500(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_157_(Stack),
+ yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_158(S, '*', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 417, Ss, Stack, T, Ts, Tzr);
-yeccpars2_158(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 418, Ss, Stack, T, Ts, Tzr);
-yeccpars2_158(S, 'and', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 419, Ss, Stack, T, Ts, Tzr);
-yeccpars2_158(S, 'band', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 420, Ss, Stack, T, Ts, Tzr);
-yeccpars2_158(S, 'div', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 421, Ss, Stack, T, Ts, Tzr);
-yeccpars2_158(S, 'rem', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 422, Ss, Stack, T, Ts, Tzr);
yeccpars2_158(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_400(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_158_(Stack),
+ yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_159(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 405, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, '++', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 406, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 407, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, '--', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 408, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, 'bor', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 409, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, 'bsl', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 410, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, 'bsr', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 411, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, 'bxor', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 412, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, 'or', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 413, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(S, 'xor', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 414, Ss, Stack, T, Ts, Tzr);
-yeccpars2_159(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_300(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_159: see yeccpars2_83
-yeccpars2_160(S, '/=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 394, Ss, Stack, T, Ts, Tzr);
-yeccpars2_160(S, '<', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 395, Ss, Stack, T, Ts, Tzr);
-yeccpars2_160(S, '=/=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 396, Ss, Stack, T, Ts, Tzr);
-yeccpars2_160(S, '=:=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 397, Ss, Stack, T, Ts, Tzr);
-yeccpars2_160(S, '=<', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 398, Ss, Stack, T, Ts, Tzr);
-yeccpars2_160(S, '==', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 399, Ss, Stack, T, Ts, Tzr);
-yeccpars2_160(S, '>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 400, Ss, Stack, T, Ts, Tzr);
-yeccpars2_160(S, '>=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 401, Ss, Stack, T, Ts, Tzr);
yeccpars2_160(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_200(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_160_(Stack),
+ yeccgoto_fun_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_161(S, 'andalso', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 391, Ss, Stack, T, Ts, Tzr);
-yeccpars2_161(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_160(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_161: see yeccpars2_10
-yeccpars2_162(S, 'orelse', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 389, Ss, Stack, T, Ts, Tzr);
yeccpars2_162(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_150(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_162_(Stack),
+ yeccgoto_fun_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_163(S, '!', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 385, Ss, Stack, T, Ts, Tzr);
-yeccpars2_163(S, '=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 386, Ss, Stack, T, Ts, Tzr);
yeccpars2_163(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_163_(Stack),
+ yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_164_(Stack),
+ yeccgoto_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_165(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 383, Ss, Stack, T, Ts, Tzr);
-yeccpars2_165(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 348, Ss, Stack, T, Ts, Tzr);
-yeccpars2_165(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_165_(Stack),
- yeccgoto_attr_val(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_165(S, 'of', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 166, Ss, Stack, T, Ts, Tzr).
-yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_166: see yeccpars2_45
-yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_167(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 168, Ss, Stack, T, Ts, Tzr).
yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_168_(Stack),
+ yeccgoto_case_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_169(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_169_(Stack),
- yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_169(S, 'end', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 170, Ss, Stack, T, Ts, Tzr).
yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_170_(Stack),
+ yeccgoto_expr_max(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_171(S, '||', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 129, Ss, Stack, T, Ts, Tzr);
+yeccpars2_171(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_179(S, Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_172: see yeccpars2_18
+yeccpars2_172(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_172_(Stack),
+ yeccgoto_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_173(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_173(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_173(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_173_(Stack),
+ yeccgoto_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_174(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_174: see yeccpars2_45
yeccpars2_175(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_175_(Stack),
+ yeccgoto_tail(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-%% yeccpars2_176: see yeccpars2_18
+%% yeccpars2_176: see yeccpars2_45
-yeccpars2_177(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 323, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_177(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_177(S, ']', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 178, Ss, Stack, T, Ts, Tzr).
-yeccpars2_178(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, '+', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_178(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_178_(Stack),
+ yeccgoto_tail(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+yeccpars2_179(S, ',', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, '-', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_179(S, ']', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 308, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_178(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-%% yeccpars2_179: see yeccpars2_173
+yeccpars2_179(S, '|', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr).
yeccpars2_180(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_180_(Stack),
+ yeccgoto_tail(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_181: see yeccpars2_173
+yeccpars2_181(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_181(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_181(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_181(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_181(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_182: see yeccpars2_173
+yeccpars2_182(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_bit_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_183(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 195, Ss, Stack, T, Ts, Tzr);
yeccpars2_183(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_183_(Stack),
+ yeccpars2_194(194, Cat, [183 | Ss], NewStack, T, Ts, Tzr).
+yeccpars2_184(S, '||', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 191, Ss, Stack, T, Ts, Tzr);
yeccpars2_184(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_185(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 285, Ss, Stack, T, Ts, Tzr);
-yeccpars2_185(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_185(S, '>>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 190, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_186: see yeccpars2_173
+yeccpars2_186(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
+yeccpars2_186(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_186_(Stack),
+ yeccgoto_bin_elements(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
yeccpars2_187(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_187_(Stack),
+ yeccgoto_binary(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_188(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_prefix_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_188(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_188(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_189(S, '[', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 259, Ss, Stack, T, Ts, Tzr).
+yeccpars2_189(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_189_(Stack),
+ yeccgoto_bin_elements(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_190(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, 'after', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 249, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_190(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_190(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_190_(Stack),
+ yeccgoto_binary(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_191(S, string, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 191, Ss, Stack, T, Ts, Tzr);
-yeccpars2_191(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_strings(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_191: see yeccpars2_45
-%% yeccpars2_192: see yeccpars2_173
+yeccpars2_192(S, '>>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr).
yeccpars2_193(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_193_(Stack),
+ yeccgoto_binary_comprehension(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_194(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 198, Ss, Stack, T, Ts, Tzr);
-yeccpars2_194(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_194(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 199, Ss, Stack, T, Ts, Tzr);
+yeccpars2_194(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_194_(Stack),
+ yeccpars2_198(_S, Cat, [194 | Ss], NewStack, T, Ts, Tzr).
-yeccpars2_195(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 203, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_195: see yeccpars2_181
-yeccpars2_196(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 201, Ss, Stack, T, Ts, Tzr);
yeccpars2_196(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_196_(Stack),
- yeccgoto_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_bit_size_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_197: see yeccpars2_173
+yeccpars2_197(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_197_(Stack),
+ yeccgoto_opt_bit_size_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_198(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_198_(Stack),
- yeccgoto_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_bin_element(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_199(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 200, Ss, Stack, T, Ts, Tzr).
+yeccpars2_199(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 202, Ss, Stack, T, Ts, Tzr).
yeccpars2_200(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_|Nss] = Ss,
NewStack = yeccpars2_200_(Stack),
- yeccgoto_expr_max(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_opt_bit_type_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_201: see yeccpars2_173
+yeccpars2_201(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 205, Ss, Stack, T, Ts, Tzr);
+yeccpars2_201(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_201_(Stack),
+ yeccgoto_bit_type_list(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_202(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 203, Ss, Stack, T, Ts, Tzr);
yeccpars2_202(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
NewStack = yeccpars2_202_(Stack),
- yeccgoto_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_bit_type(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+
+yeccpars2_203(S, integer, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 204, Ss, Stack, T, Ts, Tzr).
-yeccpars2_203(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_204(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_203_(Stack),
- yeccgoto_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_204_(Stack),
+ yeccgoto_bit_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_204(S, 'of', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 208, Ss, Stack, T, Ts, Tzr);
-yeccpars2_204(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_210(S, Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_205: see yeccpars2_199
-yeccpars2_205(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_206(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_205_(Stack),
- yeccgoto_try_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_206_(Stack),
+ yeccgoto_bit_type_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_206: see yeccpars2_173
+yeccpars2_207(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_207_(Stack),
+ yeccgoto_bit_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_207(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 228, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_207(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_208(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_208_(Stack),
+ yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_208: see yeccpars2_173
+yeccpars2_209(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 210, Ss, Stack, T, Ts, Tzr).
-yeccpars2_209(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
-yeccpars2_209(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_209_(Stack),
- yeccpars2_215(215, Cat, [209 | Ss], NewStack, T, Ts, Tzr).
+yeccpars2_210(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_210_(Stack),
+ yeccgoto_expr_max(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_210(S, 'after', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 206, Ss, Stack, T, Ts, Tzr);
-yeccpars2_210(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 207, Ss, Stack, T, Ts, Tzr).
+yeccpars2_211(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 213, Ss, Stack, T, Ts, Tzr);
+yeccpars2_211(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr).
-yeccpars2_211(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 212, Ss, Stack, T, Ts, Tzr);
-yeccpars2_211(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_211_(Stack),
- yeccgoto_cr_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_212(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_212_(Stack),
+ yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_212: see yeccpars2_173
+yeccpars2_213(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 227, Ss, Stack, T, Ts, Tzr).
-yeccpars2_213(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_213_(Stack),
- yeccgoto_cr_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_214(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr);
+yeccpars2_214(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_224(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_214(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_214_(Stack),
- yeccgoto_try_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_215(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 226, Ss, Stack, T, Ts, Tzr).
-yeccpars2_215(S, '->', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_216(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 224, Ss, Stack, T, Ts, Tzr);
+yeccpars2_216(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_216_(Stack),
+ yeccgoto_record_fields(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+
+yeccpars2_217(S, '=', Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_216: see yeccpars2_173
+yeccpars2_218(S, '=', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 220, Ss, Stack, T, Ts, Tzr).
-yeccpars2_217(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_219(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
- NewStack = yeccpars2_217_(Stack),
- yeccgoto_clause_guard(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-yeccpars2_218(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 219, Ss, Stack, T, Ts, Tzr);
-yeccpars2_218(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_218_(Stack),
- yeccgoto_guard(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_219: see yeccpars2_173
+ NewStack = yeccpars2_219_(Stack),
+ yeccgoto_record_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_220(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_220_(Stack),
- yeccgoto_guard(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_220: see yeccpars2_45
yeccpars2_221(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
NewStack = yeccpars2_221_(Stack),
- yeccgoto_cr_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_record_field(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_222: see yeccpars2_173
+%% yeccpars2_222: see yeccpars2_45
yeccpars2_223(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_223_(Stack),
- yeccgoto_clause_body(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_record_field(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_224(S, 'after', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 241, Ss, Stack, T, Ts, Tzr);
-yeccpars2_224(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 242, Ss, Stack, T, Ts, Tzr).
+yeccpars2_224(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 217, Ss, Stack, T, Ts, Tzr);
+yeccpars2_224(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 218, Ss, Stack, T, Ts, Tzr).
-yeccpars2_225(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 239, Ss, Stack, T, Ts, Tzr);
yeccpars2_225(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_225_(Stack),
- yeccgoto_try_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_record_fields(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_226(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
yeccpars2_226(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_226_(Stack),
- yeccpars2_215(237, Cat, [226 | Ss], NewStack, T, Ts, Tzr).
+ yeccgoto_record_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_227(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 233, Ss, Stack, T, Ts, Tzr);
yeccpars2_227(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_atomic(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_227_(Stack),
+ yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_228(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 229, Ss, Stack, T, Ts, Tzr);
-yeccpars2_228(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_228: see yeccpars2_45
-%% yeccpars2_229: see yeccpars2_173
+yeccpars2_229(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_229_(Stack),
+ yeccgoto_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_230(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
-yeccpars2_230(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_230_(Stack),
- yeccpars2_215(231, Cat, [230 | Ss], NewStack, T, Ts, Tzr).
+yeccpars2_230(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_230(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_231: see yeccpars2_215
+%% yeccpars2_231: see yeccpars2_230
yeccpars2_232(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_232_(Stack),
- yeccgoto_try_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_233: see yeccpars2_173
+ yeccgoto_expr_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_234(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
-yeccpars2_234(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_234_(Stack),
- yeccpars2_215(235, Cat, [234 | Ss], NewStack, T, Ts, Tzr).
+yeccpars2_233(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_233_(Stack),
+ yeccgoto_expr_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_235: see yeccpars2_215
+%% yeccpars2_234: see yeccpars2_230
-yeccpars2_236(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_236_(Stack),
- yeccgoto_try_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_235(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_235_(Stack),
+ yeccgoto_expr_150(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_237: see yeccpars2_215
+%% yeccpars2_236: see yeccpars2_230
-yeccpars2_238(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_237(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_238_(Stack),
- yeccgoto_try_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_237_(Stack),
+ yeccgoto_expr_160(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_239: see yeccpars2_207
+%% yeccpars2_238: see yeccpars2_230
+
+yeccpars2_239(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_240(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_240_(Stack),
- yeccgoto_try_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_241: see yeccpars2_173
+yeccpars2_241(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_242(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_242_(Stack),
- yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_243(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 244, Ss, Stack, T, Ts, Tzr).
+yeccpars2_243(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_244(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_244_(Stack),
- yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_245(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 246, Ss, Stack, T, Ts, Tzr).
+yeccpars2_245(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_246(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_246_(Stack),
- yeccgoto_try_catch(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_247(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_247_(Stack),
- yeccgoto_strings(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_200(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_248(S, 'after', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 253, Ss, Stack, T, Ts, Tzr);
-yeccpars2_248(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_248: see yeccpars2_230
-%% yeccpars2_249: see yeccpars2_173
+%% yeccpars2_249: see yeccpars2_230
-%% yeccpars2_250: see yeccpars2_215
+yeccpars2_250(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_251(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 252, Ss, Stack, T, Ts, Tzr).
+yeccpars2_251(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_list_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_252(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_252_(Stack),
- yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_253: see yeccpars2_173
+yeccpars2_253(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_list_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_254(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_254_(Stack),
- yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_255: see yeccpars2_215
+yeccpars2_255(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_256(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 257, Ss, Stack, T, Ts, Tzr).
+yeccpars2_256(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_257(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_257_(Stack),
- yeccgoto_receive_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_258(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 273, Ss, Stack, T, Ts, Tzr).
+yeccpars2_258(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_259: see yeccpars2_173
+yeccpars2_259(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_260(S, '||', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 261, Ss, Stack, T, Ts, Tzr).
+yeccpars2_260(S, '*', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr);
+yeccpars2_260(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 263, Ss, Stack, T, Ts, Tzr);
+yeccpars2_260(S, 'and', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr);
+yeccpars2_260(S, 'band', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 265, Ss, Stack, T, Ts, Tzr);
+yeccpars2_260(S, 'div', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr);
+yeccpars2_260(S, 'rem', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 267, Ss, Stack, T, Ts, Tzr);
+yeccpars2_260(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_260_(Stack),
+ yeccgoto_expr_400(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_261: see yeccpars2_173
+%% yeccpars2_261: see yeccpars2_230
-yeccpars2_262(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 272, Ss, Stack, T, Ts, Tzr).
+yeccpars2_262(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_263(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 270, Ss, Stack, T, Ts, Tzr);
yeccpars2_263(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_263_(Stack),
- yeccgoto_lc_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_264(S, '<-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 268, Ss, Stack, T, Ts, Tzr);
yeccpars2_264(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_lc_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_265(S, '<=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr);
yeccpars2_265(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_266: see yeccpars2_173
+yeccpars2_266(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_267(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_267_(Stack),
- yeccgoto_lc_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_268: see yeccpars2_173
+yeccpars2_268(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_268_(Stack),
+ yeccgoto_expr_500(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_269(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
NewStack = yeccpars2_269_(Stack),
- yeccgoto_lc_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_300(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_270: see yeccpars2_173
+yeccpars2_270(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_270_(Stack),
+ yeccgoto_function_call(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_271(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_271_(Stack),
- yeccgoto_lc_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_271(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 274, Ss, Stack, T, Ts, Tzr).
-yeccpars2_272(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_272_(Stack),
- yeccgoto_list_comprehension(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_272: see yeccpars2_181
yeccpars2_273(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
NewStack = yeccpars2_273_(Stack),
- yeccgoto_query_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_expr_800(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_274(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 280, Ss, Stack, T, Ts, Tzr).
+yeccpars2_274(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_274_(Stack),
+ yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_275(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 278, Ss, Stack, T, Ts, Tzr);
-yeccpars2_275(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_275_(Stack),
- yeccgoto_if_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_275(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 276, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_276: see yeccpars2_215
+yeccpars2_276(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 278, Ss, Stack, T, Ts, Tzr);
+yeccpars2_276(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr).
yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_,_|Nss] = Ss,
NewStack = yeccpars2_277_(Stack),
- yeccgoto_if_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_278: see yeccpars2_173
+yeccpars2_278(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 279, Ss, Stack, T, Ts, Tzr).
yeccpars2_279(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_279_(Stack),
- yeccgoto_if_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_280(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
NewStack = yeccpars2_280_(Stack),
- yeccgoto_if_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_argument_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_281(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 299, Ss, Stack, T, Ts, Tzr).
+yeccpars2_281(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_281_(Stack),
+ yeccgoto_expr_600(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_282(S, ';', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr);
-yeccpars2_282(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_282_(Stack),
- yeccgoto_fun_clauses(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_282(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 283, Ss, Stack, T, Ts, Tzr).
-yeccpars2_283(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 291, Ss, Stack, T, Ts, Tzr);
-yeccpars2_283(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 292, Ss, Stack, T, Ts, Tzr).
+yeccpars2_283(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 285, Ss, Stack, T, Ts, Tzr);
+yeccpars2_283(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 214, Ss, Stack, T, Ts, Tzr).
-yeccpars2_284(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
yeccpars2_284(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_|Nss] = Ss,
NewStack = yeccpars2_284_(Stack),
- yeccpars2_215(289, Cat, [284 | Ss], NewStack, T, Ts, Tzr).
+ yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_285(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 287, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
yeccpars2_285(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_285(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 286, Ss, Stack, T, Ts, Tzr).
-yeccpars2_286(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 288, Ss, Stack, T, Ts, Tzr).
+yeccpars2_286(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_286_(Stack),
+ yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_287(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_287_(Stack),
- yeccgoto_argument_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_287(S, '->', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 90, Ss, Stack, T, Ts, Tzr);
+yeccpars2_287(S, ':-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr).
yeccpars2_288(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_|Nss] = Ss,
NewStack = yeccpars2_288_(Stack),
- yeccgoto_argument_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_rule_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_289: see yeccpars2_215
+yeccpars2_289(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_289_(Stack),
+ yeccgoto_function_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_290(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_290_(Stack),
- yeccgoto_fun_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_290: see yeccpars2_45
-yeccpars2_291(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 296, Ss, Stack, T, Ts, Tzr).
+yeccpars2_291(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_291_(Stack),
+ yeccgoto_rule_body(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_292: see yeccpars2_18
+yeccpars2_292(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 428, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, '.', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 68, Ss, Stack, T, Ts, Tzr);
+yeccpars2_292(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_293(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 294, Ss, Stack, T, Ts, Tzr).
+yeccpars2_293(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 296, Ss, Stack, T, Ts, Tzr);
+yeccpars2_293(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr).
-yeccpars2_294(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 295, Ss, Stack, T, Ts, Tzr).
+yeccpars2_294(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_294_(Stack),
+ yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_295(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_295_(Stack),
- yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_295(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr).
-yeccpars2_296(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
- NewStack = yeccpars2_296_(Stack),
- yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_296(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 297, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_297: see yeccpars2_9
+yeccpars2_297(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 298, Ss, Stack, T, Ts, Tzr);
+yeccpars2_297(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 299, Ss, Stack, T, Ts, Tzr);
+yeccpars2_297(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_spec_fun(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_298(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_298_(Stack),
- yeccgoto_fun_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_298(S, integer, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr).
-yeccpars2_299(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_299_(Stack),
- yeccgoto_fun_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_299(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 300, Ss, Stack, T, Ts, Tzr).
+yeccpars2_300(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 301, Ss, Stack, T, Ts, Tzr);
yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_300_(Stack),
- yeccgoto_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_301(S, 'of', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_301(S, integer, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 302, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_302: see yeccpars2_173
+yeccpars2_302(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 303, Ss, Stack, T, Ts, Tzr).
-yeccpars2_303(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 304, Ss, Stack, T, Ts, Tzr).
+yeccpars2_303(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_303_(Stack),
+ yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_304(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_304_(Stack),
- yeccgoto_case_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_304(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 305, Ss, Stack, T, Ts, Tzr).
-yeccpars2_305(S, 'end', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 306, Ss, Stack, T, Ts, Tzr).
+yeccpars2_305(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_305_(Stack),
+ yeccgoto_spec_fun(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_306(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_306_(Stack),
- yeccgoto_expr_max(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_306: see yeccpars2_295
-yeccpars2_307(S, '||', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 261, Ss, Stack, T, Ts, Tzr);
-yeccpars2_307(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_315(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_307(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 423, Ss, Stack, T, Ts, Tzr).
+yeccpars2_308(S, ';', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 421, Ss, Stack, T, Ts, Tzr);
yeccpars2_308(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
NewStack = yeccpars2_308_(Stack),
- yeccgoto_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type_sigs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_309(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 409, Ss, Stack, T, Ts, Tzr);
yeccpars2_309(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_309_(Stack),
- yeccgoto_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type_sig(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_310: see yeccpars2_173
+yeccpars2_310(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 323, Ss, Stack, T, Ts, Tzr);
+yeccpars2_310(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_310(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_310(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_310(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_310(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr);
+yeccpars2_310(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_cont_310(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 321, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 322, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(S, '<<', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 324, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(S, '[', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 325, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 326, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(S, 'fun', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 327, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(S, integer, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 328, Ss, Stack, T, Ts, Tzr);
+yeccpars2_cont_310(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 330, Ss, Stack, T, Ts, Tzr).
yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_311_(Stack),
- yeccgoto_tail(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_312: see yeccpars2_173
-
-yeccpars2_313(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 314, Ss, Stack, T, Ts, Tzr).
-
+ yeccgoto_type_400(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_312(S, '*', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr);
+yeccpars2_312(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 263, Ss, Stack, T, Ts, Tzr);
+yeccpars2_312(S, 'and', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr);
+yeccpars2_312(S, 'band', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 265, Ss, Stack, T, Ts, Tzr);
+yeccpars2_312(S, 'div', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr);
+yeccpars2_312(S, 'rem', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 267, Ss, Stack, T, Ts, Tzr);
+yeccpars2_312(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_type_300(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_313(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 250, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 252, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, '..', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 404, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, 'bor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, 'bsl', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 255, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, 'bsr', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 256, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, 'bxor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 257, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, 'or', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 258, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(S, 'xor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 259, Ss, Stack, T, Ts, Tzr);
+yeccpars2_313(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_type_200(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_314(S, '|', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 401, Ss, Stack, T, Ts, Tzr);
yeccpars2_314(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_314_(Stack),
- yeccgoto_tail(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_top_type_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_315(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 310, Ss, Stack, T, Ts, Tzr);
-yeccpars2_315(S, ']', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 311, Ss, Stack, T, Ts, Tzr);
-yeccpars2_315(S, '|', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 312, Ss, Stack, T, Ts, Tzr).
+yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_type_500(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_316(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_316_(Stack),
- yeccgoto_tail(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_316(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 398, Ss, Stack, T, Ts, Tzr).
-yeccpars2_317(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_317(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_317(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_317(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_317(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_317(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_top_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_318(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 396, Ss, Stack, T, Ts, Tzr);
yeccpars2_318(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_bit_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_318_(Stack),
+ yeccgoto_top_types(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_319(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 331, Ss, Stack, T, Ts, Tzr);
-yeccpars2_319(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_319_(Stack),
- yeccpars2_330(330, Cat, [319 | Ss], NewStack, T, Ts, Tzr).
+yeccpars2_319(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 336, Ss, Stack, T, Ts, Tzr);
+yeccpars2_319(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_320(S, '||', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 327, Ss, Stack, T, Ts, Tzr);
yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_expr_max(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_321(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 326, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_322(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 324, Ss, Stack, T, Ts, Tzr);
-yeccpars2_322(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_322_(Stack),
- yeccgoto_bin_elements(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-
-yeccpars2_323(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_323_(Stack),
- yeccgoto_binary(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_324(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
+yeccpars2_321(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 384, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_322(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_322(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_322(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_322(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_322(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr);
+yeccpars2_322(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_323(S, '->', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 380, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_324(S, '>>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 365, Ss, Stack, T, Ts, Tzr);
yeccpars2_324(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_324(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccpars2_325(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_325_(Stack),
- yeccgoto_bin_elements(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
+ yeccpars1(S, 366, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_325(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_325(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_325(S, ']', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 358, Ss, Stack, T, Ts, Tzr);
+yeccpars2_325(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_325(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_325(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr);
+yeccpars2_325(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_326(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 347, Ss, Stack, T, Ts, Tzr);
+yeccpars2_326(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 348, Ss, Stack, T, Ts, Tzr);
yeccpars2_326(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_326_(Stack),
- yeccgoto_binary(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_327: see yeccpars2_173
+yeccpars2_327(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 337, Ss, Stack, T, Ts, Tzr).
-yeccpars2_328(S, '>>', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr).
+yeccpars2_328(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_329(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 334, Ss, Stack, T, Ts, Tzr);
yeccpars2_329(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_329_(Stack),
- yeccgoto_binary_comprehension(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-yeccpars2_330(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 335, Ss, Stack, T, Ts, Tzr);
-yeccpars2_330(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_330_(Stack),
- yeccpars2_334(_S, Cat, [330 | Ss], NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_331: see yeccpars2_317
+yeccpars2_330(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_330(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_330(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_330(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_330(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr);
+yeccpars2_330(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 332, Ss, Stack, T, Ts, Tzr);
+yeccpars2_330(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_331(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 333, Ss, Stack, T, Ts, Tzr).
yeccpars2_332(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_bit_size_expr(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_332_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_333(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_333_(Stack),
- yeccgoto_opt_bit_size_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_334(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_334(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_334(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_334(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_334(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_334(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 336, Ss, Stack, T, Ts, Tzr);
+yeccpars2_334(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_335(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_334_(Stack),
- yeccgoto_bin_element(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_335: see yeccpars2_18
+ NewStack = yeccpars2_335_(Stack),
+ yeccgoto_top_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_336(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_336_(Stack),
- yeccgoto_opt_bit_type_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_337(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 341, Ss, Stack, T, Ts, Tzr);
-yeccpars2_337(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_337_(Stack),
- yeccgoto_bit_type_list(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_337(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 340, Ss, Stack, T, Ts, Tzr);
+yeccpars2_337(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 341, Ss, Stack, T, Ts, Tzr).
-yeccpars2_338(S, ':', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 339, Ss, Stack, T, Ts, Tzr);
-yeccpars2_338(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_338_(Stack),
- yeccgoto_bit_type(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_338(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 346, Ss, Stack, T, Ts, Tzr).
-yeccpars2_339(S, integer, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 340, Ss, Stack, T, Ts, Tzr).
+yeccpars2_339(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_fun_type_100(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_340(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_340(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 323, Ss, Stack, T, Ts, Tzr);
+yeccpars2_340(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_340(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_340(S, '...', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 342, Ss, Stack, T, Ts, Tzr);
+yeccpars2_340(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_340(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_340(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr);
+yeccpars2_340(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_341(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_340_(Stack),
- yeccgoto_bit_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_341: see yeccpars2_18
+ NewStack = yeccpars2_341_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_342(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_342_(Stack),
- yeccgoto_bit_type_list(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_342(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 343, Ss, Stack, T, Ts, Tzr).
-yeccpars2_343(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_343_(Stack),
- yeccgoto_bit_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_343(S, '->', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 344, Ss, Stack, T, Ts, Tzr).
-yeccpars2_344(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_344_(Stack),
- yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_344: see yeccpars2_322
-yeccpars2_345(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 365, Ss, Stack, T, Ts, Tzr).
+yeccpars2_345(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_345_(Stack),
+ yeccgoto_fun_type_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_346(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 200, Ss, Stack, T, Ts, Tzr);
-yeccpars2_346(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 347, Ss, Stack, T, Ts, Tzr);
-yeccpars2_346(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 348, Ss, Stack, T, Ts, Tzr).
+yeccpars2_346(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_346_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_347(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_347(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
+yeccpars2_347(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 355, Ss, Stack, T, Ts, Tzr);
yeccpars2_347(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
yeccpars2_347(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_347(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
-yeccpars2_347(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
yeccpars2_347(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_347(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 182, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
yeccpars2_347(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_347(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
yeccpars2_347(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_347(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 352, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr);
yeccpars2_347(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_348: see yeccpars2_32
+yeccpars2_348(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 349, Ss, Stack, T, Ts, Tzr).
-yeccpars2_349(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_349_(Stack),
- yeccgoto_typed_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_349(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 350, Ss, Stack, T, Ts, Tzr).
-yeccpars2_350(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_350_(Stack),
- yeccgoto_typed_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_350(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 352, Ss, Stack, T, Ts, Tzr);
+yeccpars2_350(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_350(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
+yeccpars2_350(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_350(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_350(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 329, Ss, Stack, T, Ts, Tzr);
+yeccpars2_350(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
yeccpars2_351(S, ')', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 364, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 353, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_352: see yeccpars2_194
+yeccpars2_352(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_352_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_353(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 363, Ss, Stack, T, Ts, Tzr).
+yeccpars2_353(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_353_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_354(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 360, Ss, Stack, T, Ts, Tzr);
-yeccpars2_354(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_354_(Stack),
- yeccgoto_typed_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_354(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 356, Ss, Stack, T, Ts, Tzr).
-yeccpars2_355(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 356, Ss, Stack, T, Ts, Tzr);
-yeccpars2_355(S, '::', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 357, Ss, Stack, T, Ts, Tzr);
yeccpars2_355(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_355_(Stack),
- yeccgoto_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_356: see yeccpars2_173
+yeccpars2_356(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_356_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_357: see yeccpars2_32
+yeccpars2_357(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 359, Ss, Stack, T, Ts, Tzr);
+yeccpars2_357(S, ']', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 360, Ss, Stack, T, Ts, Tzr).
yeccpars2_358(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_|Nss] = Ss,
NewStack = yeccpars2_358_(Stack),
- yeccgoto_typed_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-yeccpars2_359(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_359_(Stack),
- yeccgoto_typed_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_360: see yeccpars2_173
+yeccpars2_359(S, '...', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 361, Ss, Stack, T, Ts, Tzr).
-yeccpars2_361(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_360(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_361_(Stack),
- yeccgoto_typed_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_360_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+yeccpars2_361(S, ']', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 362, Ss, Stack, T, Ts, Tzr).
yeccpars2_362(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_362_(Stack),
- yeccgoto_typed_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_363(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_363_(Stack),
- yeccgoto_typed_record_fields(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_363(S, '>>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 379, Ss, Stack, T, Ts, Tzr).
-yeccpars2_364(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
- NewStack = yeccpars2_364_(Stack),
- yeccgoto_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_364(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 372, Ss, Stack, T, Ts, Tzr);
+yeccpars2_364(S, '>>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 373, Ss, Stack, T, Ts, Tzr).
yeccpars2_365(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
+ [_|Nss] = Ss,
NewStack = yeccpars2_365_(Stack),
- yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_366(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 368, Ss, Stack, T, Ts, Tzr);
-yeccpars2_366(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 369, Ss, Stack, T, Ts, Tzr).
+yeccpars2_366(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 367, Ss, Stack, T, Ts, Tzr).
-yeccpars2_367(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_367_(Stack),
- yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_367(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 369, Ss, Stack, T, Ts, Tzr);
+yeccpars2_367(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_310(S, Cat, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_368: see yeccpars2_18
+yeccpars2_368(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_368_(Stack),
+ yeccgoto_bin_base_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_369(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 373, Ss, Stack, T, Ts, Tzr);
-yeccpars2_369(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 374, Ss, Stack, T, Ts, Tzr);
-yeccpars2_369(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_369(S, '*', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 370, Ss, Stack, T, Ts, Tzr);
+yeccpars2_369(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccgoto_type(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_370(S, '}', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 381, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_370: see yeccpars2_319
-yeccpars2_371(S, ',', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 379, Ss, Stack, T, Ts, Tzr);
yeccpars2_371(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_371_(Stack),
- yeccgoto_record_fields(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-
-yeccpars2_372(S, '=', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 377, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_bin_unit_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_373(S, '=', Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_372(S, var, Ss, Stack, T, Ts, Tzr) ->
yeccpars1(S, 375, Ss, Stack, T, Ts, Tzr).
-yeccpars2_374(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_374_(Stack),
- yeccgoto_record_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_373(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_373_(Stack),
+ yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_375: see yeccpars2_173
+yeccpars2_374(S, '>>', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 378, Ss, Stack, T, Ts, Tzr).
-yeccpars2_376(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_376_(Stack),
- yeccgoto_record_field(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_375(S, ':', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 376, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_377: see yeccpars2_173
+yeccpars2_376(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 377, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_377(S, '*', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 370, Ss, Stack, T, Ts, Tzr).
yeccpars2_378(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_378_(Stack),
- yeccgoto_record_field(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-yeccpars2_379(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 373, Ss, Stack, T, Ts, Tzr);
-yeccpars2_379(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_18(S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_380(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_379(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_380_(Stack),
- yeccgoto_record_fields(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_379_(Stack),
+ yeccgoto_binary_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_381(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_381_(Stack),
- yeccgoto_record_tuple(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_380: see yeccpars2_322
-yeccpars2_382(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_381(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_,_|Nss] = Ss,
- NewStack = yeccpars2_382_(Stack),
- yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_381_(Stack),
+ yeccgoto_fun_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_383: see yeccpars2_347
+yeccpars2_382(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 383, Ss, Stack, T, Ts, Tzr).
-yeccpars2_384(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_383(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_384_(Stack),
- yeccgoto_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_383_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+yeccpars2_384(S, '{', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 385, Ss, Stack, T, Ts, Tzr).
-yeccpars2_385(S, '#', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 172, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, '(', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 197, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, '+', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 174, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, '-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 175, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 176, Ss, Stack, T, Ts, Tzr);
yeccpars2_385(S, atom, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 11, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 180, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, 'not', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 188, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, 'spec', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 12, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, var, Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 193, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 194, Ss, Stack, T, Ts, Tzr);
-yeccpars2_385(S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 388, Ss, Stack, T, Ts, Tzr);
+yeccpars2_385(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 389, Ss, Stack, T, Ts, Tzr).
-%% yeccpars2_386: see yeccpars2_385
+yeccpars2_386(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 394, Ss, Stack, T, Ts, Tzr).
+yeccpars2_387(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 392, Ss, Stack, T, Ts, Tzr);
yeccpars2_387(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
NewStack = yeccpars2_387_(Stack),
- yeccgoto_expr_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_field_types(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_388(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_388_(Stack),
- yeccgoto_expr_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_388(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 390, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_389(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_389_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_389: see yeccpars2_385
+%% yeccpars2_390: see yeccpars2_322
-yeccpars2_390(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_391(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_390_(Stack),
- yeccgoto_expr_150(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_391_(Stack),
+ yeccgoto_field_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_391: see yeccpars2_385
+yeccpars2_392(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 388, Ss, Stack, T, Ts, Tzr).
-yeccpars2_392(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_393(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_392_(Stack),
- yeccgoto_expr_160(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_393: see yeccpars2_385
+ NewStack = yeccpars2_393_(Stack),
+ yeccgoto_field_types(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_394(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_394_(Stack),
+ yeccgoto_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_395(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_395_(Stack),
+ yeccgoto_type_500(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_396(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_396: see yeccpars2_322
yeccpars2_397(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_397_(Stack),
+ yeccgoto_top_types(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_398(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_398(S, '->', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 399, Ss, Stack, T, Ts, Tzr).
-yeccpars2_399(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_399: see yeccpars2_322
yeccpars2_400(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_400_(Stack),
+ yeccgoto_fun_type(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_401(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_comp_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_401: see yeccpars2_334
yeccpars2_402(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
NewStack = yeccpars2_402_(Stack),
- yeccgoto_expr_200(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_403: see yeccpars2_385
-
-%% yeccpars2_404: see yeccpars2_385
+ yeccgoto_top_type_100(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_403: see yeccpars2_334
+
+%% yeccpars2_404: see yeccpars2_334
+
+yeccpars2_405(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 250, Ss, Stack, T, Ts, Tzr);
+yeccpars2_405(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 252, Ss, Stack, T, Ts, Tzr);
+yeccpars2_405(S, 'bor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 254, Ss, Stack, T, Ts, Tzr);
+yeccpars2_405(S, 'bsl', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 255, Ss, Stack, T, Ts, Tzr);
+yeccpars2_405(S, 'bsr', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 256, Ss, Stack, T, Ts, Tzr);
+yeccpars2_405(S, 'bxor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 257, Ss, Stack, T, Ts, Tzr);
+yeccpars2_405(S, 'or', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 258, Ss, Stack, T, Ts, Tzr);
+yeccpars2_405(S, 'xor', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 259, Ss, Stack, T, Ts, Tzr);
yeccpars2_405(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
-
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_405_(Stack),
+ yeccgoto_type_200(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+yeccpars2_406(S, '*', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 262, Ss, Stack, T, Ts, Tzr);
+yeccpars2_406(S, '/', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 263, Ss, Stack, T, Ts, Tzr);
+yeccpars2_406(S, 'and', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 264, Ss, Stack, T, Ts, Tzr);
+yeccpars2_406(S, 'band', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 265, Ss, Stack, T, Ts, Tzr);
+yeccpars2_406(S, 'div', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 266, Ss, Stack, T, Ts, Tzr);
+yeccpars2_406(S, 'rem', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 267, Ss, Stack, T, Ts, Tzr);
yeccpars2_406(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_list_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_406_(Stack),
+ yeccgoto_type_300(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_407(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_407: see yeccpars2_334
yeccpars2_408(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_list_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_408_(Stack),
+ yeccgoto_type_400(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_409(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_409(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 412, Ss, Stack, T, Ts, Tzr);
+yeccpars2_409(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 413, Ss, Stack, T, Ts, Tzr).
yeccpars2_410(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_410_(Stack),
+ yeccgoto_type_sig(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_411(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 419, Ss, Stack, T, Ts, Tzr);
yeccpars2_411(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ NewStack = yeccpars2_411_(Stack),
+ yeccgoto_type_guards(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_412(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_412(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 416, Ss, Stack, T, Ts, Tzr).
-yeccpars2_413(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_413(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 414, Ss, Stack, T, Ts, Tzr).
-yeccpars2_414(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_add_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_414: see yeccpars2_322
-yeccpars2_415(S, '*', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 417, Ss, Stack, T, Ts, Tzr);
-yeccpars2_415(S, '/', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 418, Ss, Stack, T, Ts, Tzr);
-yeccpars2_415(S, 'and', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 419, Ss, Stack, T, Ts, Tzr);
-yeccpars2_415(S, 'band', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 420, Ss, Stack, T, Ts, Tzr);
-yeccpars2_415(S, 'div', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 421, Ss, Stack, T, Ts, Tzr);
-yeccpars2_415(S, 'rem', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 422, Ss, Stack, T, Ts, Tzr);
yeccpars2_415(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
NewStack = yeccpars2_415_(Stack),
- yeccgoto_expr_400(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type_guard(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_416: see yeccpars2_385
+%% yeccpars2_416: see yeccpars2_322
-yeccpars2_417(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_417(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 418, Ss, Stack, T, Ts, Tzr).
yeccpars2_418(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_418_(Stack),
+ yeccgoto_type_guard(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_419(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_419: see yeccpars2_409
yeccpars2_420(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_420_(Stack),
+ yeccgoto_type_guards(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_421(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_421: see yeccpars2_295
yeccpars2_422(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccgoto_mult_op(hd(Ss), Cat, Ss, Stack, T, Ts, Tzr).
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_422_(Stack),
+ yeccgoto_type_sigs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_423(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_,_,_|Nss] = Ss,
NewStack = yeccpars2_423_(Stack),
- yeccgoto_expr_500(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type_spec(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_424(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
+ [_|Nss] = Ss,
NewStack = yeccpars2_424_(Stack),
- yeccgoto_expr_300(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_type_spec(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_425(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_425_(Stack),
- yeccgoto_function_call(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-
-%% yeccpars2_426: see yeccpars2_18
+ yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_427: see yeccpars2_317
+yeccpars2_426(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 450, Ss, Stack, T, Ts, Tzr);
+yeccpars2_426(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 432, Ss, Stack, T, Ts, Tzr);
+yeccpars2_426(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_426_(Stack),
+ yeccgoto_attr_val(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_428(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_427(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_428_(Stack),
- yeccgoto_expr_800(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_427_(Stack),
+ yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_429(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_|Nss] = Ss,
- NewStack = yeccpars2_429_(Stack),
- yeccgoto_expr_900(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_428: see yeccpars2_45
-%% yeccpars2_430: see yeccpars2_18
+yeccpars2_429(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 449, Ss, Stack, T, Ts, Tzr).
+yeccpars2_430(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 210, Ss, Stack, T, Ts, Tzr);
+yeccpars2_430(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 431, Ss, Stack, T, Ts, Tzr);
+yeccpars2_430(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 432, Ss, Stack, T, Ts, Tzr).
+
+yeccpars2_431(S, '#', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 44, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, '(', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 45, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, '+', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 47, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, '-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 48, Ss, Stack, T, Ts, Tzr);
yeccpars2_431(S, '.', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 433, Ss, Stack, T, Ts, Tzr);
+ yeccpars1(S, 49, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 52, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, 'bnot', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 54, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, 'catch', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 56, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, 'not', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 62, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, var, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 67, Ss, Stack, T, Ts, Tzr);
yeccpars2_431(S, '{', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 369, Ss, Stack, T, Ts, Tzr).
+ yeccpars1(S, 436, Ss, Stack, T, Ts, Tzr);
+yeccpars2_431(S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_cont_13(S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccpars2_432(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
- NewStack = yeccpars2_432_(Stack),
- yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_432: see yeccpars2_322
-%% yeccpars2_433: see yeccpars2_18
+yeccpars2_433(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_433_(Stack),
+ yeccgoto_typed_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_434(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_,_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_434_(Stack),
- yeccgoto_record_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_typed_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_435(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_435_(Stack),
- yeccgoto_expr_600(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+yeccpars2_435(S, ')', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 448, Ss, Stack, T, Ts, Tzr).
-yeccpars2_436(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
-yeccpars2_436(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_436_(Stack),
- yeccpars2_438(438, Cat, [436 | Ss], NewStack, T, Ts, Tzr).
+%% yeccpars2_436: see yeccpars2_68
-yeccpars2_437(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_437_(Stack),
- yeccgoto_clause_args(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_437(S, '}', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 447, Ss, Stack, T, Ts, Tzr).
-yeccpars2_438(S, '->', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 222, Ss, Stack, T, Ts, Tzr);
-yeccpars2_438(S, ':-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 441, Ss, Stack, T, Ts, Tzr).
+yeccpars2_438(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 444, Ss, Stack, T, Ts, Tzr);
+yeccpars2_438(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_438_(Stack),
+ yeccgoto_typed_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
+yeccpars2_439(S, ',', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 440, Ss, Stack, T, Ts, Tzr);
+yeccpars2_439(S, '::', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 441, Ss, Stack, T, Ts, Tzr);
yeccpars2_439(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
NewStack = yeccpars2_439_(Stack),
- yeccgoto_rule_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_exprs(hd(Ss), Cat, Ss, NewStack, T, Ts, Tzr).
-yeccpars2_440(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_,_,_|Nss] = Ss,
- NewStack = yeccpars2_440_(Stack),
- yeccgoto_function_clause(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_440: see yeccpars2_45
-%% yeccpars2_441: see yeccpars2_173
+%% yeccpars2_441: see yeccpars2_322
yeccpars2_442(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_442_(Stack),
- yeccgoto_rule_body(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_typed_expr(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_443(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
+ [_,_|Nss] = Ss,
NewStack = yeccpars2_443_(Stack),
- yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_typed_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_444(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- [_|Nss] = Ss,
- NewStack = yeccpars2_444_(Stack),
- yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+%% yeccpars2_444: see yeccpars2_45
-%% yeccpars2_445: see yeccpars2_18
+yeccpars2_445(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_445_(Stack),
+ yeccgoto_typed_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
yeccpars2_446(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
NewStack = yeccpars2_446_(Stack),
- yeccgoto_function_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ yeccgoto_typed_exprs(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_447: see yeccpars2_9
+yeccpars2_447(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_447_(Stack),
+ yeccgoto_typed_record_fields(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_448(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
yeccpars2_448(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
NewStack = yeccpars2_448_(Stack),
- yeccpars2_215(449, Cat, [448 | Ss], NewStack, T, Ts, Tzr).
+ yeccgoto_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+yeccpars2_449(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_,_,_|Nss] = Ss,
+ NewStack = yeccpars2_449_(Stack),
+ yeccgoto_attribute(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+%% yeccpars2_450: see yeccpars2_431
-%% yeccpars2_449: see yeccpars2_215
+yeccpars2_451(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_451_(Stack),
+ yeccgoto_attr_val(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+yeccpars2_452(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_452_(Stack),
+ yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccpars2_450(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_453(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_|Nss] = Ss,
- NewStack = yeccpars2_450_(Stack),
+ NewStack = yeccpars2_453_(Stack),
yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_451: see yeccpars2_18
+yeccpars2_454(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 456, Ss, Stack, T, Ts, Tzr).
-yeccpars2_452(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccpars2_455(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
[_,_|Nss] = Ss,
- NewStack = yeccpars2_452_(Stack),
- yeccgoto_rule_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+ NewStack = yeccpars2_455_(Stack),
+ yeccgoto_function_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-%% yeccpars2_453: see yeccpars2_9
+%% yeccpars2_456: see yeccpars2_10
-yeccpars2_454(S, 'when', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 216, Ss, Stack, T, Ts, Tzr);
-yeccpars2_454(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- NewStack = yeccpars2_454_(Stack),
- yeccpars2_455(455, Cat, [454 | Ss], NewStack, T, Ts, Tzr).
+yeccpars2_457(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
+yeccpars2_457(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_457_(Stack),
+ yeccpars2_83(458, Cat, [457 | Ss], NewStack, T, Ts, Tzr).
-yeccpars2_455(S, ':-', Ss, Stack, T, Ts, Tzr) ->
- yeccpars1(S, 441, Ss, Stack, T, Ts, Tzr).
+%% yeccpars2_458: see yeccpars2_83
+
+yeccpars2_459(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_|Nss] = Ss,
+ NewStack = yeccpars2_459_(Stack),
+ yeccgoto_form(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
-yeccgoto_add_op(159, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(404, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_460(S, atom, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 462, Ss, Stack, T, Ts, Tzr).
-yeccgoto_argument_list(9=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_437(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_argument_list(155=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_425(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_argument_list(185, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_284(284, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_argument_list(297, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_284(284, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_argument_list(447=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_437(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_argument_list(453=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_437(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_atom1(0, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_9(9, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(14, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(18, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(23, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(31, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_88(88, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(32, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(36, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(40, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(44, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(50, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(56, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(84, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(89, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_92(92, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(94, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(96, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_92(92, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(99, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(100, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_101(101, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(102, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(112, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(115, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(117, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(119, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_122(122, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(123, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(126, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_122(122, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(132, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_133(133, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(172, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_366(366, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_344(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(185, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_283(283, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_227(227, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_227(227, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(292, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_293(293, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(335, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_338(338, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(341, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_338(338, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(348, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(357, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_30(30, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(368=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_382(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(369, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_372(372, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(379, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_372(372, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(426=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_429(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(430, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_431(431, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(433=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_434(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_171(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(445, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_9(447, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atom1(451, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_9(453, Cat, Ss, Stack, T, Ts, Tzr).
+yeccpars2_461(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ [_,_|Nss] = Ss,
+ NewStack = yeccpars2_461_(Stack),
+ yeccgoto_rule_clauses(hd(Nss), Cat, Nss, NewStack, T, Ts, Tzr).
+
+%% yeccpars2_462: see yeccpars2_10
+
+yeccpars2_463(S, 'when', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 84, Ss, Stack, T, Ts, Tzr);
+yeccpars2_463(_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ NewStack = yeccpars2_463_(Stack),
+ yeccpars2_464(464, Cat, [463 | Ss], NewStack, T, Ts, Tzr).
+
+yeccpars2_464(S, ':-', Ss, Stack, T, Ts, Tzr) ->
+ yeccpars1(S, 290, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_add_op(33, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(249, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_add_op(313, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_334(403, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_add_op(405, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_334(403, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_argument_list(10=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_12(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_argument_list(29=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_270(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_argument_list(59, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_151(151, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_argument_list(161, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_151(151, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_argument_list(456=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_12(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_argument_list(462=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_12(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_atomic(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_atomic(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_atomic(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_atomic(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_atomic(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_atomic(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_170(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_attr_val(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_169(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_atomic(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_43(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_attr_val(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_427(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_attribute(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_8(8, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_bin_base_type(35, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_68(68, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_bin_base_type(324, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_364(364, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_bin_element(177, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_322(322, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_bin_element(324, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_322(322, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_bin_element(50, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_186(186, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_bin_element(188, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_186(186, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_bin_elements(177, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_321(321, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_bin_elements(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_325(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_bin_elements(50, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_185(185, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_bin_elements(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_189(_S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_bin_unit_type(35, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_67(67, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_bin_unit_type(76, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_78(78, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_bin_unit_type(324, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_363(363, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_bin_unit_type(372, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_374(374, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_binary(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(177, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_320(320, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(50, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_184(184, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_133(133, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_133(133, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_binary(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_133(133, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_binary(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_binary(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_265(265, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_265(265, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_265(265, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_168(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_265(265, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_133(133, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_42(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_binary_comprehension(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_binary_comprehension(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_binary_comprehension(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_binary_comprehension(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_binary_comprehension(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_comprehension(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_167(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_binary_type(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(32=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(40=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(44=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(94=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(99=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(102=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(112=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(123=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(348=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_binary_type(357=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_29(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_bit_expr(177, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_bit_expr(324, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_bit_size_expr(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_333(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_bit_type(335, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_337(337, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_bit_type(341, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_337(337, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_bit_type_list(335=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_336(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_bit_type_list(341=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_342(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_comprehension(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_41(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_binary_type(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(319=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(322=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(325=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(330=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(334=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(340=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(344=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(350=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(367=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(370=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(380=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(390=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(396=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(399=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(401=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(407=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(414=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(432=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_binary_type(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_320(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_bit_expr(50, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_183(183, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_bit_expr(188, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_183(183, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_bit_size_expr(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_197(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_bit_type(199, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_201(201, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_bit_type(205, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_201(201, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_bit_type_list(199=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_200(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_bit_type_list(205=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_206(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_case_expr(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_case_expr(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_case_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_case_expr(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_case_expr(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_case_expr(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_166(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_clause_args(9, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_436(436, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_args(447, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_448(448, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_args(453, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_454(454, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_clause_body(215=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_221(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_232(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(235=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_236(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(237=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_238(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(250, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_251(251, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(255, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_256(256, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(276=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(289=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_290(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(438=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_440(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_body(449=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_440(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_clause_guard(209, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(215, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_guard(226, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(237, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_guard(230, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(231, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_guard(234, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(235, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_guard(284, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(289, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_guard(436, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_438(438, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_guard(448, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(449, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_clause_guard(454, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_455(455, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_comp_op(160, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(393, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_cr_clause(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_211(211, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_cr_clause(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_211(211, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_cr_clause(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_211(211, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_cr_clause(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_211(211, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_cr_clauses(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_248(248, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_cr_clauses(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_210(210, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_cr_clauses(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_213(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_cr_clauses(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_303(303, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_case_expr(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_40(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_clause_args(10, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_11(11, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_args(456, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_457(457, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_args(462, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_463(463, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_clause_body(83=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_89(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(99=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_100(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(103=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_104(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(105=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_106(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(118, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_119(119, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(123, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_124(124, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(144=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(159=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_160(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(287=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_289(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_body(458=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_289(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_clause_guard(11, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_287(287, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_guard(77, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(83, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_guard(94, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(105, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_guard(98, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(99, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_guard(102, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(103, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_guard(151, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(159, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_guard(457, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(458, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_clause_guard(463, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_464(464, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_comp_op(34, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(238, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_cr_clause(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_79(79, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_cr_clause(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_79(79, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_cr_clause(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_79(79, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_cr_clause(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_79(79, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_cr_clauses(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_116(116, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_cr_clauses(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_78(78, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_cr_clauses(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_81(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_cr_clauses(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_167(167, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_165(165, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_346(346, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_307(307, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_301(301, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_300(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(190, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(45, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_209(209, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_199(199, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_226(226, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_209(209, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_209(209, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_230(230, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_234(234, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_226(226, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(250, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(255, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_260(260, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_264(264, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_267(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_269(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_264(264, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_209(209, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_315(315, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_264(264, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_355(355, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_355(355, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_355(355, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_376(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_378(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_196(196, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_264(264, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_expr(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_171(171, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_165(165, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_77(77, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_94(94, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_77(77, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_77(77, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_98(98, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_102(102, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_94(94, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(118, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(123, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_128(128, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_132(132, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_135(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_137(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_132(132, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_77(77, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_179(179, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_177(177, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_132(132, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_221(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_223(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_132(132, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_426(426, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_430(430, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_439(439, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_439(439, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_439(439, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_39(39, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_100(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_100(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_388(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_387(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_100(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_164(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_233(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_232(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_100(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_38(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_150(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_150(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_390(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_150(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_163(163, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_235(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_150(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_37(37, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_160(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_160(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_392(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_160(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_162(162, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_237(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_160(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_36(36, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_200(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_200(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_200(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_161(161, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_200(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_35(35, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_300(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_300(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_402(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_424(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_300(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_160(160, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_247(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_269(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_300(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_34(34, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_400(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_400(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(393, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(403, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_400(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_159(159, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(238, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(248, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_400(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_33(33, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_500(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_500(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(238, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(248, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_500(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(393, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(403, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(404, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_415(415, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_500(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_158(158, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_260(260, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_500(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_32(32, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_600(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_600(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_600(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_600(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_423(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_600(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_157(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_268(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_600(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_31(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_700(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_435(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_281(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_700(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_700(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_700(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_700(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_156(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_700(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_30(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_800(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(147, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(20, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_800(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(238, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(248, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_800(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_800(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(393, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(403, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(404, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(416, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_800(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_155(155, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_800(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_29(29, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_900(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(147, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(20, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_900(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(238, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(248, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_900(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_900(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(393, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(403, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(404, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(416, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_900(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_154(154, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_900(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_expr_max(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(147, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_318(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(20, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_182(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_207(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_182(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_196(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_max(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(238, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(248, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_max(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_expr_max(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_343(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_318(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_332(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(393, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(403, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(404, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(416, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_428(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_expr_max(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_153(153, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_exprs(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_305(305, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_218(218, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_204(204, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_195(195, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_202(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_245(245, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_218(218, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_218(218, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_223(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_243(243, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_218(218, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_286(286, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_351(351, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_195(195, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_202(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_362(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_exprs(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_384(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_field_type(89, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_91(91, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_field_type(96, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_91(91, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_field_types(89, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_90(90, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_field_types(96=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_97(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_273(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_expr_max(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_exprs(13, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_26(26, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_169(169, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_86(86, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_72(72, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_69(69, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_113(113, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_86(86, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_86(86, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_91(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_111(111, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_86(86, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_229(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_435(435, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_69(69, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_229(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_446(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_exprs(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_451(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_field_type(385, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_387(387, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_field_type(392, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_387(387, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_field_types(385, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_386(386, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_field_types(392=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_393(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_form(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_7(7, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_fun_clause(185, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_282(282, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_clause(297, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_282(282, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_fun_clause(59, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_150(150, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_clause(161, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_150(150, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_fun_clauses(185, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_281(281, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_clauses(297=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_298(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_fun_clauses(59, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_149(149, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_clauses(161=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_162(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_fun_expr(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_fun_expr(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_fun_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_fun_expr(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_fun_expr(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_expr(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_152(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_fun_type(16, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_22(22, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_type(19, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_22(22, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_type(47=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_49(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_fun_type(128, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_22(22, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_fun_type_100(47, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_48(48, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_expr(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_25(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_fun_type(295, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_309(309, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_type(306, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_309(309, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_type(337=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_339(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_fun_type(421, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_309(309, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_fun_type_100(337, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_338(338, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_function(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_6(6, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_function_call(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_function_call(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_function_call(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_function_call(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_call(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_151(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_function_call(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_24(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_function_clause(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_clause(445, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccgoto_function_clause(454, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_5(5, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_function_clauses(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_4(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_function_clauses(445=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_446(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_guard(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(276, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_guard(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_217(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_guard(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_220(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_guard(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_215(276, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_if_clause(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_275(275, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_clause(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_275(275, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_if_clauses(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_274(274, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_clauses(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_279(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_function_clauses(454=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_455(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_guard(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(144, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_guard(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_85(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_guard(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_88(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_guard(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_83(144, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_if_clause(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_143(143, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_clause(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_143(143, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_if_clauses(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_142(142, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_clauses(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_147(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_if_expr(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_if_expr(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_if_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_if_expr(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_if_expr(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_if_expr(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_150(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_int_type(23, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(32, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(36, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(40, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(44, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(50, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(56, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(84, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(94, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(99, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(102, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(110=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_111(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(112, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(115, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(117, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(123, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(348, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_int_type(357, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_28(28, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_lc_expr(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_263(263, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_lc_expr(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_263(263, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_lc_expr(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_263(263, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_lc_expr(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_263(263, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_lc_exprs(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_262(262, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_lc_exprs(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_271(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_lc_exprs(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_328(328, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_lc_exprs(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_442(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_if_expr(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_23(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_lc_expr(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_131(131, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_lc_expr(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_131(131, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_lc_expr(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_131(131, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_lc_expr(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_131(131, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_lc_exprs(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_130(130, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_lc_exprs(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_139(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_lc_exprs(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_192(192, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_lc_exprs(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_291(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_list(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_149(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_22(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_list_comprehension(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(63, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_126(126, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list_comprehension(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(189, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_258(258, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list_comprehension(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list_comprehension(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_list_comprehension(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_list_comprehension(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_148(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_list_op(159, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(403, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_mult_op(158, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(416, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_mult_op(415, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_385(416, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_opt_bit_size_expr(319, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_330(330, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_opt_bit_type_list(330=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_334(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_list_comprehension(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_21(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_list_op(33, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(248, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_mult_op(32, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(261, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_mult_op(260, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_230(261, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_mult_op(312, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_334(407, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_mult_op(406, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_334(407, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_opt_bit_size_expr(183, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_194(194, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_opt_bit_type_list(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_198(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_prefix_op(13, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(177, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_317(317, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(178, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(179, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(181, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(182, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(186, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(190, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(192, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(194, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(197, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(201, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(206, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(208, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(212, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(216, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(219, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(50, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_181(181, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(188, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_181(181, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(222, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(229, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(233, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(241, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(238, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(248, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(249, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(253, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(259, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(261, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(266, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(268, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(270, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(278, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(285, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(302, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(310, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(312, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(324, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_317(317, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(327, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(322, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(325, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(330, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(334, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(340, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(344, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(347, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(375, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(377, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(383, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(385, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(386, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(389, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(391, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_prefix_op(393, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(350, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(380, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(390, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(396, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(399, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(401, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(403, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(404, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(407, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(414, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(416, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(432, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_prefix_op(441, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_147(147, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_319(319, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_prefix_op(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_query_expr(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_query_expr(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_query_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_query_expr(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_query_expr(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_query_expr(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_146(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_query_expr(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_19(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_receive_expr(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_receive_expr(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_receive_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_receive_expr(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_receive_expr(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_receive_expr(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_145(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_record_expr(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_expr(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_144(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_record_field(369, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_371(371, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_field(379, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_371(371, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_record_fields(369, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_370(370, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_fields(379=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_380(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_record_tuple(366=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_367(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_record_tuple(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_432(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_receive_expr(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_18(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_record_expr(13, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(20, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(45, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(51, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(53, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(55, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(56, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(60, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(64, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(66, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(68, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(74, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(76, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(80, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(84, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(87, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(90, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(97, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(101, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(109, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(117, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(121, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(127, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(129, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(134, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(136, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(138, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(146, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(166, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(174, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(176, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(191, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(220, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(222, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(228, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(230, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(231, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(234, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(236, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(238, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(248, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(249, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(261, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(290, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(292, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(431, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_expr(450, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_17(17, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_record_field(214, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_216(216, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_field(224, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_216(216, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_record_fields(214, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_215(215, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_fields(224=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_225(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_record_tuple(211=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_212(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_tuple(276=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_277(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_record_tuple(283=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_284(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_rule(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_3(3, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_rule_body(438=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_439(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_rule_body(455=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_439(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_rule_body(287=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_288(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_rule_body(464=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_288(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_rule_clause(0, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_2(2, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_rule_clause(451, Cat, Ss, Stack, T, Ts, Tzr) ->
+yeccgoto_rule_clause(460, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_2(2, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_rule_clauses(0=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
yeccpars2_1(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_rule_clauses(451=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_452(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_rule_clauses(460=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_461(_S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_spec_fun(14, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_16(16, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_spec_fun(18, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_16(19, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_spec_fun(293, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_295(295, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_spec_fun(296, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_295(306, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_strings(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(65=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_115(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_strings(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_strings(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_247(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_strings(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_strings(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_strings(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_strings(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_143(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_tail(307=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_309(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tail(315=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_316(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_top_type(23, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(32, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_86(86, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(36, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_59(59, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(40, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(50, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_57(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_85(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(94=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_95(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(99, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(102, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(112, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_116(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(123, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_27(27, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(348=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_349(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type(357=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_358(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_top_type_100(23=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(32=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(36=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(40=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(44=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_45(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(94=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(99=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(102=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(112=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(115=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_118(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(123=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(348=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_type_100(357=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_26(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_top_types(23, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_25(25, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_types(40, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_41(41, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_types(50, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_25(25, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_types(99, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_106(106, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_types(102, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_103(103, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_types(112=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_113(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_top_types(123, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_124(124, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_try_catch(204=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_205(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_catch(210=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_214(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_try_clause(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_225(225, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_clause(239, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_225(225, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_try_clauses(207, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_224(224, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_clauses(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_240(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_strings(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_16(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_tail(171=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_173(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tail(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_180(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_top_type(310, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_318(318, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(322, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_382(382, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(325, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_357(357, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(330, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_318(318, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(340, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_318(318, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(344=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_345(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(347, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_318(318, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(350, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_318(318, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(380=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_381(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(390=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_391(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(396, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_318(318, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(399=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_400(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(414=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_415(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(416, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_318(318, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(432=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_433(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_442(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_top_type_100(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(322=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(325=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(330=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(334=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_335(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(340=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(344=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(350=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(380=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(390=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(396=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(399=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(401=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_402(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(414=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(432=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_type_100(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_317(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_top_types(310, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_316(316, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_types(330, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_331(331, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_types(340, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_316(316, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_types(347, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_354(354, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_types(350, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_351(351, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_types(396=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_397(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_top_types(416, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_417(417, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_try_catch(72=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_73(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_catch(78=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_82(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_try_clause(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_93(93, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_clause(107, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_93(93, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_try_clauses(75, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_92(92, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_clauses(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_108(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_try_expr(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_try_expr(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_try_expr(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_try_expr(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_try_expr(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_try_expr(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_142(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_try_expr(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr).
yeccgoto_tuple(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(147=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(173=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(177=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(178=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(179=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(20=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(45=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(50=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(51=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(53=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(55=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(56=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(60=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(64=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(66=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(68=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(74=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(75=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(76=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(80=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(84=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(87=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(90=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(97=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(101=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(107=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(109=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(117=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(121=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(127=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(129=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(134=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(136=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(138=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(146=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(166=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(174=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(176=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_tuple(181=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(182=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(186=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(190=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(192=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(194=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(197=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(201=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(206=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(207=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(208=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(212=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(216=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(219=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(188=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(191=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(195=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(220=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_tuple(222=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(229=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(233=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(239=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(241=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(228=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(230=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(231=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(234=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(236=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(238=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(248=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_tuple(249=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(253=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(259=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
yeccgoto_tuple(261=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(266=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(268=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(270=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(278=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(285=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(302=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(312=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(317=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(324=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(327=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(331=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(352=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(375=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(377=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(385=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(386=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(389=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(391=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(393=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(427=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_tuple(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_141(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_type(23, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(32, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(36, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(40, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(44, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(50, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(56, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(84, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(94, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(99, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(102, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(112, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(115, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(117, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(123, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(348, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type(357, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_24(24, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_type_guard(119, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_121(121, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type_guard(126, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_121(121, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_type_guards(119=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_120(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type_guards(126=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_127(_S, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_type_sig(16, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_21(21, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type_sig(19, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_21(21, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type_sig(128, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_21(21, Cat, Ss, Stack, T, Ts, Tzr).
-
-yeccgoto_type_sigs(16=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_139(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type_sigs(19, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_20(20, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_type_sigs(128=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_129(_S, Cat, Ss, Stack, T, Ts, Tzr).
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(272=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(290=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(428=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(436=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_tuple(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_14(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(319=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_395(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(322=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(325=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(330=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(334=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(340=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(344=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(350=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(367=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_368(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(370=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_371(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(380=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(390=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(396=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(399=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(401=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(407=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(414=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(432=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_315(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_200(310, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(322, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(325, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(330, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(334, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(340, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(344, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(347, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(350, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(380, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(390, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(396, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(399, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(401, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(414, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(416, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(432, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_200(441, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_314(314, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_300(310, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(322, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(325, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(330, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(334, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(340, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(344, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(347, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(350, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(380, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(390, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(396, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(399, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(401, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(404, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_405(405, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(414, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(416, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(432, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_300(441, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_313(313, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_400(310, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(322, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(325, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(330, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(334, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(340, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(344, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(347, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(350, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(380, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(390, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(396, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(399, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(401, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(403, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_406(406, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(404, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(414, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(416, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(432, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_400(441, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_312(312, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_500(310=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(322=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(325=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(330=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(334=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(340=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(344=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(350=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(380=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(390=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(396=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(399=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(401=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(403=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(404=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(407=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_408(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(414=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(416=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(432=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_500(441=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_311(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_guard(409, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_411(411, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_guard(419, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_411(411, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_guards(409=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_410(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_guards(419=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_420(_S, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_sig(295, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_308(308, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_sig(306, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_308(308, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_sig(421, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_308(308, Cat, Ss, Stack, T, Ts, Tzr).
+
+yeccgoto_type_sigs(295=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_424(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_sigs(306, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_307(307, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_type_sigs(421=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_422(_S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_type_spec(14=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_15(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_type_spec(293=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_294(_S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_typed_attr_val(13=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_140(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_typed_attr_val(173, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_345(345, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_typed_attr_val(292=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_425(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_typed_attr_val(428, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_429(429, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_typed_expr(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_354(354, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_typed_expr(356, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_354(354, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_typed_expr(360, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_354(354, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_typed_expr(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_438(438, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_typed_expr(440, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_438(438, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_typed_expr(444, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_438(438, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_typed_exprs(352, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_353(353, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_typed_exprs(356=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_359(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_typed_exprs(360=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_361(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_typed_exprs(436, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_437(437, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_typed_exprs(440=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_443(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_typed_exprs(444=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_445(_S, Cat, Ss, Stack, T, Ts, Tzr).
-yeccgoto_typed_record_fields(347=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_350(_S, Cat, Ss, Stack, T, Ts, Tzr);
-yeccgoto_typed_record_fields(383=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
- yeccpars2_350(_S, Cat, Ss, Stack, T, Ts, Tzr).
+yeccgoto_typed_record_fields(431=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_434(_S, Cat, Ss, Stack, T, Ts, Tzr);
+yeccgoto_typed_record_fields(450=_S, Cat, Ss, Stack, T, Ts, Tzr) ->
+ yeccpars2_434(_S, Cat, Ss, Stack, T, Ts, Tzr).
-compile({inline,yeccpars2_1_/1}).
--file("erl_parse.yrl", 475).
+-file("erl_parse.yrl", 487).
yeccpars2_1_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -7808,7 +7930,7 @@ yeccpars2_1_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_2_/1}).
--file("erl_parse.yrl", 477).
+-file("erl_parse.yrl", 489).
yeccpars2_2_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -7816,7 +7938,7 @@ yeccpars2_2_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_4_/1}).
--file("erl_parse.yrl", 189).
+-file("erl_parse.yrl", 197).
yeccpars2_4_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
@@ -7824,1442 +7946,1479 @@ yeccpars2_4_(__Stack0) ->
end | __Stack].
-compile({inline,yeccpars2_5_/1}).
--file("erl_parse.yrl", 191).
+-file("erl_parse.yrl", 199).
yeccpars2_5_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
[ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7834).
+-compile({inline,yeccpars2_11_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_11_(__Stack0) ->
+ [begin
+ [ ]
+ end | __Stack0].
+
-compile({inline,yeccpars2_12_/1}).
--file("erl_parse.yrl", 77).
+-file("erl_parse.yrl", 206).
yeccpars2_12_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
- { atom , ? line ( __1 ) , 'spec' }
- end | __Stack].
-
--compile({inline,yeccpars2_15_/1}).
--file("erl_parse.yrl", 75).
-yeccpars2_15_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
- [begin
- build_type_spec ( __2 , __3 )
+ element ( 1 , __1 )
end | __Stack].
--compile({inline,yeccpars2_21_/1}).
--file("erl_parse.yrl", 102).
-yeccpars2_21_(__Stack0) ->
+-compile({inline,yeccpars2_39_/1}).
+-file("erl_parse.yrl", 438).
+yeccpars2_39_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
[ __1 ]
end | __Stack].
--compile({inline,yeccpars2_27_/1}).
--file("erl_parse.yrl", 115).
-yeccpars2_27_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7979).
+-compile({inline,yeccpars2_46_/1}).
+-file("erl_parse.yrl", 434).
+yeccpars2_46_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { [ ] , ? line ( __1 ) }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7867).
--compile({inline,yeccpars2_42_/1}).
--file("erl_parse.yrl", 138).
-yeccpars2_42_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7988).
+-compile({inline,yeccpars2_70_/1}).
+-file("erl_parse.yrl", 325).
+yeccpars2_70_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , tuple , [ ] }
+ { tuple , ? line ( __1 ) , [ ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7876).
--compile({inline,yeccpars2_43_/1}).
--file("erl_parse.yrl", 139).
-yeccpars2_43_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 7997).
+-compile({inline,yeccpars2_71_/1}).
+-file("erl_parse.yrl", 326).
+yeccpars2_71_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , tuple , __2 }
+ { tuple , ? line ( __1 ) , __2 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7885).
--compile({inline,yeccpars2_45_/1}).
--file("erl_parse.yrl", 118).
-yeccpars2_45_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8006).
+-compile({inline,yeccpars2_73_/1}).
+-file("erl_parse.yrl", 408).
+yeccpars2_73_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { ann_type , ? line ( __1 ) , [ __1 , __3 ] }
+ build_try ( ? line ( __1 ) , __2 , [ ] , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7894).
--compile({inline,yeccpars2_51_/1}).
--file("erl_parse.yrl", 147).
-yeccpars2_51_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_77_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_77_(__Stack0) ->
[begin
- { type , ? line ( __1 ) , 'fun' , [ ] }
+ [ ]
+ end | __Stack0].
+
+-compile({inline,yeccpars2_79_/1}).
+-file("erl_parse.yrl", 377).
+yeccpars2_79_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ [ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7903).
--compile({inline,yeccpars2_57_/1}).
--file("erl_parse.yrl", 155).
-yeccpars2_57_(__Stack0) ->
- [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_81_/1}).
+-file("erl_parse.yrl", 378).
+yeccpars2_81_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , 'fun' ,
- [ { type , ? line ( __1 ) , any } , __7 ] }
+ [ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_58_/1}).
--file("erl_parse.yrl", 148).
-yeccpars2_58_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8038).
+-compile({inline,yeccpars2_82_/1}).
+-file("erl_parse.yrl", 406).
+yeccpars2_82_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- __3
+ build_try ( ? line ( __1 ) , __2 , __4 , __5 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7921).
--compile({inline,yeccpars2_60_/1}).
--file("erl_parse.yrl", 134).
-yeccpars2_60_(__Stack0) ->
+-compile({inline,yeccpars2_85_/1}).
+-file("erl_parse.yrl", 208).
+yeccpars2_85_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , nil , [ ] }
+ __2
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7930).
--compile({inline,yeccpars2_62_/1}).
--file("erl_parse.yrl", 135).
-yeccpars2_62_(__Stack0) ->
+-compile({inline,yeccpars2_86_/1}).
+-file("erl_parse.yrl", 441).
+yeccpars2_86_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ [ __1 ]
+ end | __Stack].
+
+-compile({inline,yeccpars2_88_/1}).
+-file("erl_parse.yrl", 442).
+yeccpars2_88_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , list , [ __2 ] }
+ [ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7939).
--compile({inline,yeccpars2_66_/1}).
--file("erl_parse.yrl", 136).
-yeccpars2_66_(__Stack0) ->
- [__7,__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8071).
+-compile({inline,yeccpars2_89_/1}).
+-file("erl_parse.yrl", 381).
+yeccpars2_89_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) ,
- nonempty_list , [ __2 ] }
+ { clause , ? line ( __1 ) , [ __1 ] , __2 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7949).
--compile({inline,yeccpars2_69_/1}).
--file("erl_parse.yrl", 171).
-yeccpars2_69_(__Stack0) ->
+-compile({inline,yeccpars2_91_/1}).
+-file("erl_parse.yrl", 211).
+yeccpars2_91_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , binary ,
- [ abstract ( 0 , ? line ( __1 ) ) ,
- abstract ( 0 , ? line ( __1 ) ) ] }
+ __2
end | __Stack].
--compile({inline,yeccpars2_72_/1}).
--file("erl_parse.yrl", 181).
-yeccpars2_72_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_93_/1}).
+-file("erl_parse.yrl", 417).
+yeccpars2_93_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- build_bin_type ( [ __1 ] , __3 )
+ [ __1 ]
end | __Stack].
--compile({inline,yeccpars2_75_/1}).
--file("erl_parse.yrl", 183).
-yeccpars2_75_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_94_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_94_(__Stack0) ->
[begin
- build_bin_type ( [ __1 , __3 ] , __5 )
- end | __Stack].
+ [ ]
+ end | __Stack0].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7976).
--compile({inline,yeccpars2_77_/1}).
--file("erl_parse.yrl", 174).
-yeccpars2_77_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_98_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_98_(__Stack0) ->
[begin
- { type , ? line ( __1 ) , binary ,
- [ __2 , abstract ( 0 , ? line ( __1 ) ) ] }
- end | __Stack].
+ [ ]
+ end | __Stack0].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7986).
--compile({inline,yeccpars2_81_/1}).
--file("erl_parse.yrl", 179).
-yeccpars2_81_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8110).
+-compile({inline,yeccpars2_100_/1}).
+-file("erl_parse.yrl", 427).
+yeccpars2_100_(__Stack0) ->
[__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , binary , [ __2 , __4 ] }
+ L = ? line ( __1 ) ,
+ { clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 7995).
--compile({inline,yeccpars2_82_/1}).
--file("erl_parse.yrl", 176).
-yeccpars2_82_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_102_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_102_(__Stack0) ->
[begin
- { type , ? line ( __1 ) , binary ,
- [ abstract ( 0 , ? line ( __1 ) ) , __2 ] }
- end | __Stack].
+ [ ]
+ end | __Stack0].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8005).
--compile({inline,yeccpars2_83_/1}).
--file("erl_parse.yrl", 151).
-yeccpars2_83_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8127).
+-compile({inline,yeccpars2_104_/1}).
+-file("erl_parse.yrl", 424).
+yeccpars2_104_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- abstract ( - normalise ( __2 ) ,
- ? line ( __2 ) )
+ L = ? line ( __1 ) ,
+ { clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8015).
--compile({inline,yeccpars2_85_/1}).
--file("erl_parse.yrl", 159).
-yeccpars2_85_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8137).
+-compile({inline,yeccpars2_106_/1}).
+-file("erl_parse.yrl", 421).
+yeccpars2_106_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , 'fun' ,
- [ { type , ? line ( __1 ) , product , [ ] } , __4 ] }
+ L = ? line ( __1 ) ,
+ { clause , L , [ { tuple , L , [ { atom , L , throw } , __1 , { var , L , '_' } ] } ] , __2 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8025).
--compile({inline,yeccpars2_87_/1}).
--file("erl_parse.yrl", 124).
-yeccpars2_87_(__Stack0) ->
+-compile({inline,yeccpars2_108_/1}).
+-file("erl_parse.yrl", 418).
+yeccpars2_108_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { paren_type , ? line ( __2 ) , [ __2 ] }
+ [ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_91_/1}).
--file("erl_parse.yrl", 165).
-yeccpars2_91_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_110_/1}).
+-file("erl_parse.yrl", 411).
+yeccpars2_110_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { __2 , [ ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8042).
--compile({inline,yeccpars2_93_/1}).
--file("erl_parse.yrl", 140).
-yeccpars2_93_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_112_/1}).
+-file("erl_parse.yrl", 413).
+yeccpars2_112_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , record , [ __2 ] }
+ { __2 , __4 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8051).
--compile({inline,yeccpars2_95_/1}).
--file("erl_parse.yrl", 168).
-yeccpars2_95_(__Stack0) ->
+-compile({inline,yeccpars2_114_/1}).
+-file("erl_parse.yrl", 415).
+yeccpars2_114_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , field_type ,
- [ __1 , __3 ] }
+ { [ ] , __2 }
end | __Stack].
--compile({inline,yeccpars2_97_/1}).
--file("erl_parse.yrl", 166).
-yeccpars2_97_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8179).
+-compile({inline,yeccpars2_115_/1}).
+-file("erl_parse.yrl", 452).
+yeccpars2_115_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { string , ? line ( __1 ) , element ( 3 , __1 ) ++ element ( 3 , __2 ) }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8069).
--compile({inline,yeccpars2_98_/1}).
--file("erl_parse.yrl", 141).
-yeccpars2_98_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8188).
+-compile({inline,yeccpars2_120_/1}).
+-file("erl_parse.yrl", 386).
+yeccpars2_120_(__Stack0) ->
[__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) ,
- record , [ __2 | __4 ] }
+ { 'receive' , ? line ( __1 ) , [ ] , __3 , __4 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8079).
--compile({inline,yeccpars2_104_/1}).
--file("erl_parse.yrl", 130).
-yeccpars2_104_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8197).
+-compile({inline,yeccpars2_122_/1}).
+-file("erl_parse.yrl", 384).
+yeccpars2_122_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { remote_type , ? line ( __1 ) ,
- [ __1 , __3 , [ ] ] }
+ { 'receive' , ? line ( __1 ) , __2 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8089).
--compile({inline,yeccpars2_105_/1}).
--file("erl_parse.yrl", 132).
-yeccpars2_105_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8206).
+-compile({inline,yeccpars2_125_/1}).
+-file("erl_parse.yrl", 388).
+yeccpars2_125_(__Stack0) ->
[__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { remote_type , ? line ( __1 ) ,
- [ __1 , __3 , __5 ] }
+ { 'receive' , ? line ( __1 ) , __2 , __4 , __5 }
end | __Stack].
--compile({inline,yeccpars2_107_/1}).
--file("erl_parse.yrl", 127).
-yeccpars2_107_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_131_/1}).
+-file("erl_parse.yrl", 318).
+yeccpars2_131_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- build_gen_type ( __1 )
+ [ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8107).
--compile({inline,yeccpars2_108_/1}).
--file("erl_parse.yrl", 128).
-yeccpars2_108_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8223).
+-compile({inline,yeccpars2_135_/1}).
+-file("erl_parse.yrl", 323).
+yeccpars2_135_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) ,
- normalise ( __1 ) , __3 }
+ { b_generate , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8117).
--compile({inline,yeccpars2_111_/1}).
--file("erl_parse.yrl", 145).
-yeccpars2_111_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8232).
+-compile({inline,yeccpars2_137_/1}).
+-file("erl_parse.yrl", 322).
+yeccpars2_137_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , range ,
- [ __1 , __4 ] }
+ { generate , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--compile({inline,yeccpars2_113_/1}).
--file("erl_parse.yrl", 116).
-yeccpars2_113_(__Stack0) ->
+-compile({inline,yeccpars2_139_/1}).
+-file("erl_parse.yrl", 319).
+yeccpars2_139_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8135).
--compile({inline,yeccpars2_116_/1}).
--file("erl_parse.yrl", 162).
-yeccpars2_116_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8249).
+-compile({inline,yeccpars2_140_/1}).
+-file("erl_parse.yrl", 315).
+yeccpars2_140_(__Stack0) ->
[__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , 'fun' ,
- [ { type , ? line ( __1 ) , product , __2 } , __5 ] }
- end | __Stack].
-
--compile({inline,yeccpars2_118_/1}).
--file("erl_parse.yrl", 122).
-yeccpars2_118_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
- [begin
- lift_unions ( __1 , __3 )
+ { lc , ? line ( __1 ) , __2 , __4 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8153).
--compile({inline,yeccpars2_120_/1}).
--file("erl_parse.yrl", 106).
-yeccpars2_120_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8258).
+-compile({inline,yeccpars2_141_/1}).
+-file("erl_parse.yrl", 431).
+yeccpars2_141_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , bounded_fun ,
- [ __1 , __3 ] }
+ { 'query' , ? line ( __1 ) , __2 }
end | __Stack].
--compile({inline,yeccpars2_121_/1}).
--file("erl_parse.yrl", 109).
-yeccpars2_121_(__Stack0) ->
+-compile({inline,yeccpars2_143_/1}).
+-file("erl_parse.yrl", 367).
+yeccpars2_143_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
[ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8171).
--compile({inline,yeccpars2_125_/1}).
--file("erl_parse.yrl", 112).
-yeccpars2_125_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8275).
+-compile({inline,yeccpars2_145_/1}).
+-file("erl_parse.yrl", 371).
+yeccpars2_145_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- { type , ? line ( __1 ) , constraint ,
- [ __1 , __3 ] }
+ { clause , ? line ( hd ( hd ( __1 ) ) ) , [ ] , __1 , __2 }
end | __Stack].
--compile({inline,yeccpars2_127_/1}).
--file("erl_parse.yrl", 110).
-yeccpars2_127_(__Stack0) ->
+-compile({inline,yeccpars2_147_/1}).
+-file("erl_parse.yrl", 368).
+yeccpars2_147_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_129_/1}).
--file("erl_parse.yrl", 103).
-yeccpars2_129_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8292).
+-compile({inline,yeccpars2_148_/1}).
+-file("erl_parse.yrl", 365).
+yeccpars2_148_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { 'if' , ? line ( __1 ) , __2 }
end | __Stack].
--compile({inline,yeccpars2_130_/1}).
--file("erl_parse.yrl", 81).
-yeccpars2_130_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_150_/1}).
+-file("erl_parse.yrl", 398).
+yeccpars2_150_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- { __2 , __3 }
+ [ __1 ]
end | __Stack].
--compile({inline,yeccpars2_133_/1}).
--file("erl_parse.yrl", 84).
-yeccpars2_133_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_151_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_151_(__Stack0) ->
[begin
- { __1 , __3 }
- end | __Stack].
+ [ ]
+ end | __Stack0].
--compile({inline,yeccpars2_136_/1}).
--file("erl_parse.yrl", 88).
-yeccpars2_136_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8316).
+-compile({inline,yeccpars2_157_/1}).
+-file("erl_parse.yrl", 394).
+yeccpars2_157_(__Stack0) ->
[__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { __1 , __3 , __5 }
+ { 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) , element ( 3 , __6 ) } }
end | __Stack].
--compile({inline,yeccpars2_138_/1}).
--file("erl_parse.yrl", 87).
-yeccpars2_138_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8325).
+-compile({inline,yeccpars2_158_/1}).
+-file("erl_parse.yrl", 392).
+yeccpars2_158_(__Stack0) ->
[__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { __1 , __3 }
+ { 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) } }
end | __Stack].
--compile({inline,yeccpars2_139_/1}).
--file("erl_parse.yrl", 80).
-yeccpars2_139_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_160_/1}).
+-file("erl_parse.yrl", 402).
+yeccpars2_160_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { __1 , __2 }
+ { Args , Pos } = __1 ,
+ { clause , Pos , 'fun' , Args , __2 , __3 }
end | __Stack].
--compile({inline,yeccpars2_140_/1}).
--file("erl_parse.yrl", 73).
-yeccpars2_140_(__Stack0) ->
+-compile({inline,yeccpars2_162_/1}).
+-file("erl_parse.yrl", 399).
+yeccpars2_162_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- build_typed_attribute ( __2 , __3 )
+ [ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_165_/1}).
--file("erl_parse.yrl", 185).
-yeccpars2_165_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8351).
+-compile({inline,yeccpars2_163_/1}).
+-file("erl_parse.yrl", 396).
+yeccpars2_163_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ build_fun ( ? line ( __1 ) , __2 )
end | __Stack].
--compile({inline,yeccpars2_169_/1}).
--file("erl_parse.yrl", 72).
-yeccpars2_169_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8360).
+-compile({inline,yeccpars2_164_/1}).
+-file("erl_parse.yrl", 214).
+yeccpars2_164_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- build_attribute ( __2 , __3 )
+ { 'catch' , ? line ( __1 ) , __2 }
end | __Stack].
--compile({inline,yeccpars2_196_/1}).
--file("erl_parse.yrl", 426).
-yeccpars2_196_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8369).
+-compile({inline,yeccpars2_168_/1}).
+-file("erl_parse.yrl", 375).
+yeccpars2_168_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { 'case' , ? line ( __1 ) , __2 , __4 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8269).
--compile({inline,yeccpars2_198_/1}).
--file("erl_parse.yrl", 317).
-yeccpars2_198_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8378).
+-compile({inline,yeccpars2_170_/1}).
+-file("erl_parse.yrl", 270).
+yeccpars2_170_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
+ [begin
+ { block , ? line ( __1 ) , __2 }
+ end | __Stack].
+
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8387).
+-compile({inline,yeccpars2_172_/1}).
+-file("erl_parse.yrl", 279).
+yeccpars2_172_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- { tuple , ? line ( __1 ) , [ ] }
+ { nil , ? line ( __1 ) }
end | __Stack].
--compile({inline,yeccpars2_200_/1}).
--file("erl_parse.yrl", 261).
-yeccpars2_200_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8396).
+-compile({inline,yeccpars2_173_/1}).
+-file("erl_parse.yrl", 280).
+yeccpars2_173_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- __2
+ { cons , ? line ( __1 ) , __2 , __3 }
end | __Stack].
--compile({inline,yeccpars2_202_/1}).
--file("erl_parse.yrl", 427).
-yeccpars2_202_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8405).
+-compile({inline,yeccpars2_175_/1}).
+-file("erl_parse.yrl", 282).
+yeccpars2_175_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { nil , ? line ( __1 ) }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8294).
--compile({inline,yeccpars2_203_/1}).
--file("erl_parse.yrl", 318).
-yeccpars2_203_(__Stack0) ->
+-compile({inline,yeccpars2_178_/1}).
+-file("erl_parse.yrl", 283).
+yeccpars2_178_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { tuple , ? line ( __1 ) , __2 }
+ __2
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8303).
--compile({inline,yeccpars2_205_/1}).
--file("erl_parse.yrl", 396).
-yeccpars2_205_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8422).
+-compile({inline,yeccpars2_180_/1}).
+-file("erl_parse.yrl", 284).
+yeccpars2_180_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- build_try ( ? line ( __1 ) , __2 , [ ] , __3 )
+ { cons , ? line ( __2 ) , __2 , __3 }
end | __Stack].
--compile({inline,yeccpars2_209_/1}).
--file("erl_parse.yrl", 201).
-yeccpars2_209_(__Stack0) ->
+-compile({inline,yeccpars2_183_/1}).
+-file("erl_parse.yrl", 300).
+yeccpars2_183_(__Stack0) ->
[begin
- [ ]
+ default
end | __Stack0].
--compile({inline,yeccpars2_211_/1}).
--file("erl_parse.yrl", 365).
-yeccpars2_211_(__Stack0) ->
+-compile({inline,yeccpars2_186_/1}).
+-file("erl_parse.yrl", 290).
+yeccpars2_186_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
[ __1 ]
end | __Stack].
--compile({inline,yeccpars2_213_/1}).
--file("erl_parse.yrl", 366).
-yeccpars2_213_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8446).
+-compile({inline,yeccpars2_187_/1}).
+-file("erl_parse.yrl", 287).
+yeccpars2_187_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
+ [begin
+ { bin , ? line ( __1 ) , [ ] }
+ end | __Stack].
+
+-compile({inline,yeccpars2_189_/1}).
+-file("erl_parse.yrl", 291).
+yeccpars2_189_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8335).
--compile({inline,yeccpars2_214_/1}).
--file("erl_parse.yrl", 394).
-yeccpars2_214_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8463).
+-compile({inline,yeccpars2_190_/1}).
+-file("erl_parse.yrl", 288).
+yeccpars2_190_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
+ [begin
+ { bin , ? line ( __1 ) , __2 }
+ end | __Stack].
+
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8472).
+-compile({inline,yeccpars2_193_/1}).
+-file("erl_parse.yrl", 317).
+yeccpars2_193_(__Stack0) ->
[__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- build_try ( ? line ( __1 ) , __2 , __4 , __5 )
+ { bc , ? line ( __1 ) , __2 , __4 }
end | __Stack].
--compile({inline,yeccpars2_217_/1}).
--file("erl_parse.yrl", 200).
-yeccpars2_217_(__Stack0) ->
+-compile({inline,yeccpars2_194_/1}).
+-file("erl_parse.yrl", 303).
+yeccpars2_194_(__Stack0) ->
+ [begin
+ default
+ end | __Stack0].
+
+-compile({inline,yeccpars2_197_/1}).
+-file("erl_parse.yrl", 299).
+yeccpars2_197_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
+ [begin
+ __2
+ end | __Stack].
+
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8496).
+-compile({inline,yeccpars2_198_/1}).
+-file("erl_parse.yrl", 294).
+yeccpars2_198_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
+ [begin
+ { bin_element , ? line ( __1 ) , __1 , __2 , __3 }
+ end | __Stack].
+
+-compile({inline,yeccpars2_200_/1}).
+-file("erl_parse.yrl", 302).
+yeccpars2_200_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
__2
end | __Stack].
--compile({inline,yeccpars2_218_/1}).
--file("erl_parse.yrl", 429).
-yeccpars2_218_(__Stack0) ->
+-compile({inline,yeccpars2_201_/1}).
+-file("erl_parse.yrl", 306).
+yeccpars2_201_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
[ __1 ]
end | __Stack].
--compile({inline,yeccpars2_220_/1}).
--file("erl_parse.yrl", 430).
-yeccpars2_220_(__Stack0) ->
+-compile({inline,yeccpars2_202_/1}).
+-file("erl_parse.yrl", 308).
+yeccpars2_202_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
+ [begin
+ element ( 3 , __1 )
+ end | __Stack].
+
+-compile({inline,yeccpars2_204_/1}).
+-file("erl_parse.yrl", 309).
+yeccpars2_204_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { element ( 3 , __1 ) , element ( 3 , __3 ) }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8368).
--compile({inline,yeccpars2_221_/1}).
--file("erl_parse.yrl", 369).
-yeccpars2_221_(__Stack0) ->
+-compile({inline,yeccpars2_206_/1}).
+-file("erl_parse.yrl", 305).
+yeccpars2_206_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { clause , ? line ( __1 ) , [ __1 ] , __2 , __3 }
+ [ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_223_/1}).
--file("erl_parse.yrl", 203).
-yeccpars2_223_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8545).
+-compile({inline,yeccpars2_207_/1}).
+-file("erl_parse.yrl", 296).
+yeccpars2_207_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- __2
+ ? mkop1 ( __1 , __2 )
end | __Stack].
--compile({inline,yeccpars2_225_/1}).
--file("erl_parse.yrl", 405).
-yeccpars2_225_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8554).
+-compile({inline,yeccpars2_208_/1}).
+-file("erl_parse.yrl", 256).
+yeccpars2_208_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { record_field , ? line ( __1 ) , { atom , ? line ( __1 ) , '' } , __2 }
end | __Stack].
--compile({inline,yeccpars2_226_/1}).
--file("erl_parse.yrl", 201).
-yeccpars2_226_(__Stack0) ->
+-compile({inline,yeccpars2_210_/1}).
+-file("erl_parse.yrl", 269).
+yeccpars2_210_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ ]
- end | __Stack0].
+ __2
+ end | __Stack].
--compile({inline,yeccpars2_230_/1}).
--file("erl_parse.yrl", 201).
-yeccpars2_230_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8571).
+-compile({inline,yeccpars2_212_/1}).
+-file("erl_parse.yrl", 340).
+yeccpars2_212_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ ]
- end | __Stack0].
+ { record , ? line ( __1 ) , element ( 3 , __2 ) , __3 }
+ end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8407).
--compile({inline,yeccpars2_232_/1}).
--file("erl_parse.yrl", 415).
-yeccpars2_232_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_216_/1}).
+-file("erl_parse.yrl", 353).
+yeccpars2_216_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- L = ? line ( __1 ) ,
- { clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 }
+ [ __1 ]
end | __Stack].
--compile({inline,yeccpars2_234_/1}).
--file("erl_parse.yrl", 201).
-yeccpars2_234_(__Stack0) ->
+-compile({inline,yeccpars2_219_/1}).
+-file("erl_parse.yrl", 350).
+yeccpars2_219_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
[ ]
- end | __Stack0].
+ end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8424).
--compile({inline,yeccpars2_236_/1}).
--file("erl_parse.yrl", 412).
-yeccpars2_236_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8596).
+-compile({inline,yeccpars2_221_/1}).
+-file("erl_parse.yrl", 356).
+yeccpars2_221_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- L = ? line ( __1 ) ,
- { clause , L , [ { tuple , L , [ __1 , __3 , { var , L , '_' } ] } ] , __4 , __5 }
+ { record_field , ? line ( __1 ) , __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8434).
--compile({inline,yeccpars2_238_/1}).
--file("erl_parse.yrl", 409).
-yeccpars2_238_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8605).
+-compile({inline,yeccpars2_223_/1}).
+-file("erl_parse.yrl", 357).
+yeccpars2_223_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- L = ? line ( __1 ) ,
- { clause , L , [ { tuple , L , [ { atom , L , throw } , __1 , { var , L , '_' } ] } ] , __2 , __3 }
+ { record_field , ? line ( __1 ) , __1 , __3 }
end | __Stack].
--compile({inline,yeccpars2_240_/1}).
--file("erl_parse.yrl", 406).
-yeccpars2_240_(__Stack0) ->
+-compile({inline,yeccpars2_225_/1}).
+-file("erl_parse.yrl", 354).
+yeccpars2_225_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_242_/1}).
--file("erl_parse.yrl", 399).
-yeccpars2_242_(__Stack0) ->
+-compile({inline,yeccpars2_226_/1}).
+-file("erl_parse.yrl", 351).
+yeccpars2_226_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { __2 , [ ] }
+ __2
end | __Stack].
--compile({inline,yeccpars2_244_/1}).
--file("erl_parse.yrl", 401).
-yeccpars2_244_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8630).
+-compile({inline,yeccpars2_227_/1}).
+-file("erl_parse.yrl", 338).
+yeccpars2_227_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { __2 , __4 }
+ { record_index , ? line ( __1 ) , element ( 3 , __2 ) , __4 }
end | __Stack].
--compile({inline,yeccpars2_246_/1}).
--file("erl_parse.yrl", 403).
-yeccpars2_246_(__Stack0) ->
+-compile({inline,yeccpars2_229_/1}).
+-file("erl_parse.yrl", 439).
+yeccpars2_229_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { [ ] , __2 }
+ [ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8476).
--compile({inline,yeccpars2_247_/1}).
--file("erl_parse.yrl", 440).
-yeccpars2_247_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8647).
+-compile({inline,yeccpars2_232_/1}).
+-file("erl_parse.yrl", 217).
+yeccpars2_232_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { string , ? line ( __1 ) , element ( 3 , __1 ) ++ element ( 3 , __2 ) }
+ { match , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8485).
--compile({inline,yeccpars2_252_/1}).
--file("erl_parse.yrl", 374).
-yeccpars2_252_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8656).
+-compile({inline,yeccpars2_233_/1}).
+-file("erl_parse.yrl", 218).
+yeccpars2_233_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'receive' , ? line ( __1 ) , [ ] , __3 , __4 }
+ ? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8494).
--compile({inline,yeccpars2_254_/1}).
--file("erl_parse.yrl", 372).
-yeccpars2_254_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8665).
+-compile({inline,yeccpars2_235_/1}).
+-file("erl_parse.yrl", 221).
+yeccpars2_235_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'receive' , ? line ( __1 ) , __2 }
+ ? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8503).
--compile({inline,yeccpars2_257_/1}).
--file("erl_parse.yrl", 376).
-yeccpars2_257_(__Stack0) ->
- [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8674).
+-compile({inline,yeccpars2_237_/1}).
+-file("erl_parse.yrl", 224).
+yeccpars2_237_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'receive' , ? line ( __1 ) , __2 , __4 , __5 }
+ ? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--compile({inline,yeccpars2_263_/1}).
--file("erl_parse.yrl", 310).
-yeccpars2_263_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8683).
+-compile({inline,yeccpars2_247_/1}).
+-file("erl_parse.yrl", 228).
+yeccpars2_247_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ ? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8520).
--compile({inline,yeccpars2_267_/1}).
--file("erl_parse.yrl", 315).
-yeccpars2_267_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8692).
+-compile({inline,yeccpars2_260_/1}).
+-file("erl_parse.yrl", 236).
+yeccpars2_260_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { b_generate , ? line ( __2 ) , __1 , __3 }
+ ? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8529).
--compile({inline,yeccpars2_269_/1}).
--file("erl_parse.yrl", 314).
-yeccpars2_269_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8701).
+-compile({inline,yeccpars2_268_/1}).
+-file("erl_parse.yrl", 240).
+yeccpars2_268_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { generate , ? line ( __2 ) , __1 , __3 }
+ ? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--compile({inline,yeccpars2_271_/1}).
--file("erl_parse.yrl", 311).
-yeccpars2_271_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8710).
+-compile({inline,yeccpars2_269_/1}).
+-file("erl_parse.yrl", 232).
+yeccpars2_269_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ ? mkop2 ( __1 , __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8546).
--compile({inline,yeccpars2_272_/1}).
--file("erl_parse.yrl", 307).
-yeccpars2_272_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8719).
+-compile({inline,yeccpars2_270_/1}).
+-file("erl_parse.yrl", 362).
+yeccpars2_270_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- { lc , ? line ( __1 ) , __2 , __4 }
+ { call , ? line ( __1 ) , __1 , element ( 1 , __2 ) }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8555).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8728).
-compile({inline,yeccpars2_273_/1}).
--file("erl_parse.yrl", 419).
+-file("erl_parse.yrl", 252).
yeccpars2_273_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'query' , ? line ( __1 ) , __2 }
+ { remote , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--compile({inline,yeccpars2_275_/1}).
--file("erl_parse.yrl", 355).
-yeccpars2_275_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8737).
+-compile({inline,yeccpars2_274_/1}).
+-file("erl_parse.yrl", 258).
+yeccpars2_274_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { record_field , ? line ( __2 ) , __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8572).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8746).
-compile({inline,yeccpars2_277_/1}).
--file("erl_parse.yrl", 359).
+-file("erl_parse.yrl", 344).
yeccpars2_277_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { clause , ? line ( hd ( hd ( __1 ) ) ) , [ ] , __1 , __2 }
+ { record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 }
end | __Stack].
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8755).
-compile({inline,yeccpars2_279_/1}).
--file("erl_parse.yrl", 356).
+-file("erl_parse.yrl", 342).
yeccpars2_279_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8589).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8764).
-compile({inline,yeccpars2_280_/1}).
--file("erl_parse.yrl", 353).
+-file("erl_parse.yrl", 435).
yeccpars2_280_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'if' , ? line ( __1 ) , __2 }
+ { __2 , ? line ( __1 ) }
end | __Stack].
--compile({inline,yeccpars2_282_/1}).
--file("erl_parse.yrl", 386).
-yeccpars2_282_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8773).
+-compile({inline,yeccpars2_281_/1}).
+-file("erl_parse.yrl", 244).
+yeccpars2_281_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ ? mkop1 ( __1 , __2 )
end | __Stack].
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8782).
-compile({inline,yeccpars2_284_/1}).
--file("erl_parse.yrl", 201).
+-file("erl_parse.yrl", 348).
yeccpars2_284_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ ]
- end | __Stack0].
+ { record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 }
+ end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8613).
--compile({inline,yeccpars2_287_/1}).
--file("erl_parse.yrl", 422).
-yeccpars2_287_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8791).
+-compile({inline,yeccpars2_286_/1}).
+-file("erl_parse.yrl", 346).
+yeccpars2_286_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { [ ] , ? line ( __1 ) }
+ { record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8622).
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8800).
-compile({inline,yeccpars2_288_/1}).
--file("erl_parse.yrl", 423).
+-file("erl_parse.yrl", 493).
yeccpars2_288_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
- [begin
- { __2 , ? line ( __1 ) }
- end | __Stack].
-
--compile({inline,yeccpars2_290_/1}).
--file("erl_parse.yrl", 390).
-yeccpars2_290_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
- [begin
- { Args , Pos } = __1 ,
- { clause , Pos , 'fun' , Args , __2 , __3 }
- end | __Stack].
-
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8640).
--compile({inline,yeccpars2_295_/1}).
--file("erl_parse.yrl", 382).
-yeccpars2_295_(__Stack0) ->
- [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) , element ( 3 , __6 ) } }
+ { clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8649).
--compile({inline,yeccpars2_296_/1}).
--file("erl_parse.yrl", 380).
-yeccpars2_296_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8809).
+-compile({inline,yeccpars2_289_/1}).
+-file("erl_parse.yrl", 203).
+yeccpars2_289_(__Stack0) ->
[__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'fun' , ? line ( __1 ) , { function , element ( 3 , __2 ) , element ( 3 , __4 ) } }
+ { clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 }
end | __Stack].
--compile({inline,yeccpars2_298_/1}).
--file("erl_parse.yrl", 387).
-yeccpars2_298_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_291_/1}).
+-file("erl_parse.yrl", 495).
+yeccpars2_291_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ __2
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8666).
--compile({inline,yeccpars2_299_/1}).
--file("erl_parse.yrl", 384).
-yeccpars2_299_(__Stack0) ->
+-compile({inline,yeccpars2_294_/1}).
+-file("erl_parse.yrl", 75).
+yeccpars2_294_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- build_fun ( ? line ( __1 ) , __2 )
+ build_type_spec ( __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8675).
-compile({inline,yeccpars2_300_/1}).
--file("erl_parse.yrl", 206).
+-file("erl_parse.yrl", 81).
yeccpars2_300_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'catch' , ? line ( __1 ) , __2 }
+ { __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8684).
--compile({inline,yeccpars2_304_/1}).
--file("erl_parse.yrl", 363).
-yeccpars2_304_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_303_/1}).
+-file("erl_parse.yrl", 85).
+yeccpars2_303_(__Stack0) ->
+ [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { 'case' , ? line ( __1 ) , __2 , __4 }
+ { __1 , __3 , __5 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8693).
--compile({inline,yeccpars2_306_/1}).
--file("erl_parse.yrl", 262).
-yeccpars2_306_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_305_/1}).
+-file("erl_parse.yrl", 84).
+yeccpars2_305_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { block , ? line ( __1 ) , __2 }
+ { __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8702).
-compile({inline,yeccpars2_308_/1}).
--file("erl_parse.yrl", 271).
+-file("erl_parse.yrl", 99).
yeccpars2_308_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+ [__1 | __Stack] = __Stack0,
[begin
- { nil , ? line ( __1 ) }
+ [ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8711).
--compile({inline,yeccpars2_309_/1}).
--file("erl_parse.yrl", 272).
-yeccpars2_309_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_318_/1}).
+-file("erl_parse.yrl", 113).
+yeccpars2_318_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- { cons , ? line ( __1 ) , __2 , __3 }
+ [ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8720).
--compile({inline,yeccpars2_311_/1}).
--file("erl_parse.yrl", 274).
-yeccpars2_311_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8874).
+-compile({inline,yeccpars2_332_/1}).
+-file("erl_parse.yrl", 152).
+yeccpars2_332_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- { nil , ? line ( __1 ) }
+ { type , ? line ( __1 ) , tuple , [ ] }
end | __Stack].
--compile({inline,yeccpars2_314_/1}).
--file("erl_parse.yrl", 275).
-yeccpars2_314_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8883).
+-compile({inline,yeccpars2_333_/1}).
+-file("erl_parse.yrl", 153).
+yeccpars2_333_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- __2
+ { type , ? line ( __1 ) , tuple , __2 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8737).
--compile({inline,yeccpars2_316_/1}).
--file("erl_parse.yrl", 276).
-yeccpars2_316_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8892).
+-compile({inline,yeccpars2_335_/1}).
+-file("erl_parse.yrl", 116).
+yeccpars2_335_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { cons , ? line ( __2 ) , __2 , __3 }
+ { ann_type , ? line ( __1 ) , [ __1 , __3 ] }
end | __Stack].
--compile({inline,yeccpars2_319_/1}).
--file("erl_parse.yrl", 292).
-yeccpars2_319_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8901).
+-compile({inline,yeccpars2_341_/1}).
+-file("erl_parse.yrl", 159).
+yeccpars2_341_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- default
- end | __Stack0].
+ { type , ? line ( __1 ) , 'fun' , [ ] }
+ end | __Stack].
--compile({inline,yeccpars2_322_/1}).
--file("erl_parse.yrl", 282).
-yeccpars2_322_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8910).
+-compile({inline,yeccpars2_345_/1}).
+-file("erl_parse.yrl", 163).
+yeccpars2_345_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { type , ? line ( __1 ) , 'fun' ,
+ [ { type , ? line ( __1 ) , any } , __5 ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8761).
--compile({inline,yeccpars2_323_/1}).
--file("erl_parse.yrl", 279).
-yeccpars2_323_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_346_/1}).
+-file("erl_parse.yrl", 160).
+yeccpars2_346_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { bin , ? line ( __1 ) , [ ] }
+ __3
end | __Stack].
--compile({inline,yeccpars2_325_/1}).
--file("erl_parse.yrl", 283).
-yeccpars2_325_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8928).
+-compile({inline,yeccpars2_352_/1}).
+-file("erl_parse.yrl", 144).
+yeccpars2_352_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { remote_type , ? line ( __1 ) ,
+ [ __1 , __3 , [ ] ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8778).
--compile({inline,yeccpars2_326_/1}).
--file("erl_parse.yrl", 280).
-yeccpars2_326_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8938).
+-compile({inline,yeccpars2_353_/1}).
+-file("erl_parse.yrl", 146).
+yeccpars2_353_(__Stack0) ->
+ [__6,__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { bin , ? line ( __1 ) , __2 }
+ { remote_type , ? line ( __1 ) ,
+ [ __1 , __3 , __5 ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8787).
--compile({inline,yeccpars2_329_/1}).
--file("erl_parse.yrl", 309).
-yeccpars2_329_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_355_/1}).
+-file("erl_parse.yrl", 141).
+yeccpars2_355_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { bc , ? line ( __1 ) , __2 , __4 }
+ build_gen_type ( __1 )
end | __Stack].
--compile({inline,yeccpars2_330_/1}).
--file("erl_parse.yrl", 295).
-yeccpars2_330_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8956).
+-compile({inline,yeccpars2_356_/1}).
+-file("erl_parse.yrl", 142).
+yeccpars2_356_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- default
- end | __Stack0].
+ { type , ? line ( __1 ) ,
+ normalise ( __1 ) , __3 }
+ end | __Stack].
--compile({inline,yeccpars2_333_/1}).
--file("erl_parse.yrl", 291).
-yeccpars2_333_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8966).
+-compile({inline,yeccpars2_358_/1}).
+-file("erl_parse.yrl", 148).
+yeccpars2_358_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
- __2
+ { type , ? line ( __1 ) , nil , [ ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8811).
--compile({inline,yeccpars2_334_/1}).
--file("erl_parse.yrl", 286).
-yeccpars2_334_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8975).
+-compile({inline,yeccpars2_360_/1}).
+-file("erl_parse.yrl", 149).
+yeccpars2_360_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { bin_element , ? line ( __1 ) , __1 , __2 , __3 }
+ { type , ? line ( __1 ) , list , [ __2 ] }
end | __Stack].
--compile({inline,yeccpars2_336_/1}).
--file("erl_parse.yrl", 294).
-yeccpars2_336_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8984).
+-compile({inline,yeccpars2_362_/1}).
+-file("erl_parse.yrl", 150).
+yeccpars2_362_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- __2
+ { type , ? line ( __1 ) ,
+ nonempty_list , [ __2 ] }
end | __Stack].
--compile({inline,yeccpars2_337_/1}).
--file("erl_parse.yrl", 298).
-yeccpars2_337_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 8994).
+-compile({inline,yeccpars2_365_/1}).
+-file("erl_parse.yrl", 179).
+yeccpars2_365_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { type , ? line ( __1 ) , binary ,
+ [ abstract ( 0 , ? line ( __1 ) ) ,
+ abstract ( 0 , ? line ( __1 ) ) ] }
end | __Stack].
--compile({inline,yeccpars2_338_/1}).
--file("erl_parse.yrl", 300).
-yeccpars2_338_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_368_/1}).
+-file("erl_parse.yrl", 189).
+yeccpars2_368_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- element ( 3 , __1 )
+ build_bin_type ( [ __1 ] , __3 )
end | __Stack].
--compile({inline,yeccpars2_340_/1}).
--file("erl_parse.yrl", 301).
-yeccpars2_340_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_371_/1}).
+-file("erl_parse.yrl", 191).
+yeccpars2_371_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { element ( 3 , __1 ) , element ( 3 , __3 ) }
+ build_bin_type ( [ __1 , __3 ] , __5 )
end | __Stack].
--compile({inline,yeccpars2_342_/1}).
--file("erl_parse.yrl", 297).
-yeccpars2_342_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9021).
+-compile({inline,yeccpars2_373_/1}).
+-file("erl_parse.yrl", 182).
+yeccpars2_373_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { type , ? line ( __1 ) , binary ,
+ [ __2 , abstract ( 0 , ? line ( __1 ) ) ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8860).
--compile({inline,yeccpars2_343_/1}).
--file("erl_parse.yrl", 288).
-yeccpars2_343_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9031).
+-compile({inline,yeccpars2_378_/1}).
+-file("erl_parse.yrl", 187).
+yeccpars2_378_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop1 ( __1 , __2 )
+ { type , ? line ( __1 ) , binary , [ __2 , __4 ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8869).
--compile({inline,yeccpars2_344_/1}).
--file("erl_parse.yrl", 248).
-yeccpars2_344_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9040).
+-compile({inline,yeccpars2_379_/1}).
+-file("erl_parse.yrl", 184).
+yeccpars2_379_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record_field , ? line ( __1 ) , { atom , ? line ( __1 ) , '' } , __2 }
+ { type , ? line ( __1 ) , binary ,
+ [ abstract ( 0 , ? line ( __1 ) ) , __2 ] }
end | __Stack].
--compile({inline,yeccpars2_349_/1}).
--file("erl_parse.yrl", 91).
-yeccpars2_349_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9050).
+-compile({inline,yeccpars2_381_/1}).
+-file("erl_parse.yrl", 167).
+yeccpars2_381_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { type_def , __1 , __3 }
+ { type , ? line ( __1 ) , 'fun' ,
+ [ { type , ? line ( __1 ) , product , [ ] } , __4 ] }
end | __Stack].
--compile({inline,yeccpars2_350_/1}).
--file("erl_parse.yrl", 90).
-yeccpars2_350_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9060).
+-compile({inline,yeccpars2_383_/1}).
+-file("erl_parse.yrl", 138).
+yeccpars2_383_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { typed_record , __1 , __3 }
+ { paren_type , ? line ( __2 ) , [ __2 ] }
end | __Stack].
--compile({inline,yeccpars2_354_/1}).
--file("erl_parse.yrl", 95).
-yeccpars2_354_(__Stack0) ->
+-compile({inline,yeccpars2_387_/1}).
+-file("erl_parse.yrl", 173).
+yeccpars2_387_(__Stack0) ->
[__1 | __Stack] = __Stack0,
[begin
[ __1 ]
end | __Stack].
--compile({inline,yeccpars2_355_/1}).
--file("erl_parse.yrl", 426).
-yeccpars2_355_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9077).
+-compile({inline,yeccpars2_389_/1}).
+-file("erl_parse.yrl", 154).
+yeccpars2_389_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { type , ? line ( __1 ) , record , [ __2 ] }
end | __Stack].
--compile({inline,yeccpars2_358_/1}).
--file("erl_parse.yrl", 100).
-yeccpars2_358_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9086).
+-compile({inline,yeccpars2_391_/1}).
+-file("erl_parse.yrl", 176).
+yeccpars2_391_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { typed , __1 , __3 }
+ { type , ? line ( __1 ) , field_type ,
+ [ __1 , __3 ] }
end | __Stack].
--compile({inline,yeccpars2_359_/1}).
--file("erl_parse.yrl", 97).
-yeccpars2_359_(__Stack0) ->
+-compile({inline,yeccpars2_393_/1}).
+-file("erl_parse.yrl", 174).
+yeccpars2_393_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_361_/1}).
--file("erl_parse.yrl", 96).
-yeccpars2_361_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9104).
+-compile({inline,yeccpars2_394_/1}).
+-file("erl_parse.yrl", 155).
+yeccpars2_394_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ { type , ? line ( __1 ) ,
+ record , [ __2 | __4 ] }
end | __Stack].
--compile({inline,yeccpars2_362_/1}).
--file("erl_parse.yrl", 98).
-yeccpars2_362_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9114).
+-compile({inline,yeccpars2_395_/1}).
+-file("erl_parse.yrl", 135).
+yeccpars2_395_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ ? mkop1 ( __1 , skip_paren ( __2 ) )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8942).
--compile({inline,yeccpars2_363_/1}).
--file("erl_parse.yrl", 93).
-yeccpars2_363_(__Stack0) ->
+-compile({inline,yeccpars2_397_/1}).
+-file("erl_parse.yrl", 114).
+yeccpars2_397_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { tuple , ? line ( __1 ) , __2 }
- end | __Stack].
-
--compile({inline,yeccpars2_364_/1}).
--file("erl_parse.yrl", 187).
-yeccpars2_364_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
- [begin
- [ __2 | __4 ]
+ [ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_365_/1}).
--file("erl_parse.yrl", 74).
-yeccpars2_365_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9131).
+-compile({inline,yeccpars2_400_/1}).
+-file("erl_parse.yrl", 170).
+yeccpars2_400_(__Stack0) ->
[__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- build_typed_attribute ( __2 , __4 )
+ { type , ? line ( __1 ) , 'fun' ,
+ [ { type , ? line ( __1 ) , product , __2 } , __5 ] }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8967).
--compile({inline,yeccpars2_367_/1}).
--file("erl_parse.yrl", 332).
-yeccpars2_367_(__Stack0) ->
+-compile({inline,yeccpars2_402_/1}).
+-file("erl_parse.yrl", 120).
+yeccpars2_402_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record , ? line ( __1 ) , element ( 3 , __2 ) , __3 }
+ lift_unions ( __1 , __3 )
end | __Stack].
--compile({inline,yeccpars2_371_/1}).
--file("erl_parse.yrl", 341).
-yeccpars2_371_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9149).
+-compile({inline,yeccpars2_405_/1}).
+-file("erl_parse.yrl", 122).
+yeccpars2_405_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ __1 ]
+ { type , ? line ( __1 ) , range ,
+ [ skip_paren ( __1 ) ,
+ skip_paren ( __3 ) ] }
end | __Stack].
--compile({inline,yeccpars2_374_/1}).
--file("erl_parse.yrl", 338).
-yeccpars2_374_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9160).
+-compile({inline,yeccpars2_406_/1}).
+-file("erl_parse.yrl", 127).
+yeccpars2_406_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- [ ]
+ ? mkop2 ( skip_paren ( __1 ) ,
+ __2 , skip_paren ( __3 ) )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 8992).
--compile({inline,yeccpars2_376_/1}).
--file("erl_parse.yrl", 344).
-yeccpars2_376_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9170).
+-compile({inline,yeccpars2_408_/1}).
+-file("erl_parse.yrl", 131).
+yeccpars2_408_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record_field , ? line ( __1 ) , __1 , __3 }
+ ? mkop2 ( skip_paren ( __1 ) ,
+ __2 , skip_paren ( __3 ) )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9001).
--compile({inline,yeccpars2_378_/1}).
--file("erl_parse.yrl", 345).
-yeccpars2_378_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9180).
+-compile({inline,yeccpars2_410_/1}).
+-file("erl_parse.yrl", 103).
+yeccpars2_410_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record_field , ? line ( __1 ) , __1 , __3 }
+ { type , ? line ( __1 ) , bounded_fun ,
+ [ __1 , __3 ] }
end | __Stack].
--compile({inline,yeccpars2_380_/1}).
--file("erl_parse.yrl", 342).
-yeccpars2_380_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_411_/1}).
+-file("erl_parse.yrl", 106).
+yeccpars2_411_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- [ __1 | __3 ]
+ [ __1 ]
end | __Stack].
--compile({inline,yeccpars2_381_/1}).
--file("erl_parse.yrl", 339).
-yeccpars2_381_(__Stack0) ->
+-compile({inline,yeccpars2_415_/1}).
+-file("erl_parse.yrl", 111).
+yeccpars2_415_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- __2
+ build_def ( __1 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9026).
--compile({inline,yeccpars2_382_/1}).
--file("erl_parse.yrl", 330).
-yeccpars2_382_(__Stack0) ->
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9206).
+-compile({inline,yeccpars2_418_/1}).
+-file("erl_parse.yrl", 109).
+yeccpars2_418_(__Stack0) ->
[__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record_index , ? line ( __1 ) , element ( 3 , __2 ) , __4 }
+ { type , ? line ( __1 ) , constraint ,
+ [ __1 , __3 ] }
end | __Stack].
--compile({inline,yeccpars2_384_/1}).
--file("erl_parse.yrl", 186).
-yeccpars2_384_(__Stack0) ->
+-compile({inline,yeccpars2_420_/1}).
+-file("erl_parse.yrl", 107).
+yeccpars2_420_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9043).
--compile({inline,yeccpars2_387_/1}).
--file("erl_parse.yrl", 209).
-yeccpars2_387_(__Stack0) ->
+-compile({inline,yeccpars2_422_/1}).
+-file("erl_parse.yrl", 100).
+yeccpars2_422_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { match , ? line ( __2 ) , __1 , __3 }
+ [ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9052).
--compile({inline,yeccpars2_388_/1}).
--file("erl_parse.yrl", 210).
-yeccpars2_388_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_423_/1}).
+-file("erl_parse.yrl", 78).
+yeccpars2_423_(__Stack0) ->
+ [__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop2 ( __1 , __2 , __3 )
+ { __2 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9061).
--compile({inline,yeccpars2_390_/1}).
--file("erl_parse.yrl", 213).
-yeccpars2_390_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_424_/1}).
+-file("erl_parse.yrl", 77).
+yeccpars2_424_(__Stack0) ->
+ [__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop2 ( __1 , __2 , __3 )
+ { __1 , __2 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9070).
--compile({inline,yeccpars2_392_/1}).
--file("erl_parse.yrl", 216).
-yeccpars2_392_(__Stack0) ->
+-compile({inline,yeccpars2_425_/1}).
+-file("erl_parse.yrl", 73).
+yeccpars2_425_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop2 ( __1 , __2 , __3 )
+ build_typed_attribute ( __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9079).
--compile({inline,yeccpars2_402_/1}).
--file("erl_parse.yrl", 220).
-yeccpars2_402_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_426_/1}).
+-file("erl_parse.yrl", 193).
+yeccpars2_426_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- ? mkop2 ( __1 , __2 , __3 )
+ [ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9088).
--compile({inline,yeccpars2_415_/1}).
--file("erl_parse.yrl", 228).
-yeccpars2_415_(__Stack0) ->
+-compile({inline,yeccpars2_427_/1}).
+-file("erl_parse.yrl", 72).
+yeccpars2_427_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop2 ( __1 , __2 , __3 )
+ build_attribute ( __2 , __3 )
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9097).
--compile({inline,yeccpars2_423_/1}).
--file("erl_parse.yrl", 232).
-yeccpars2_423_(__Stack0) ->
+-compile({inline,yeccpars2_433_/1}).
+-file("erl_parse.yrl", 88).
+yeccpars2_433_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop2 ( __1 , __2 , __3 )
+ { type_def , __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9106).
--compile({inline,yeccpars2_424_/1}).
--file("erl_parse.yrl", 224).
-yeccpars2_424_(__Stack0) ->
+-compile({inline,yeccpars2_434_/1}).
+-file("erl_parse.yrl", 87).
+yeccpars2_434_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop2 ( __1 , __2 , __3 )
+ { typed_record , __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9115).
--compile({inline,yeccpars2_425_/1}).
--file("erl_parse.yrl", 350).
-yeccpars2_425_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_438_/1}).
+-file("erl_parse.yrl", 92).
+yeccpars2_438_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- { call , ? line ( __1 ) , __1 , element ( 1 , __2 ) }
+ [ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9124).
--compile({inline,yeccpars2_428_/1}).
--file("erl_parse.yrl", 244).
-yeccpars2_428_(__Stack0) ->
- [__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_439_/1}).
+-file("erl_parse.yrl", 438).
+yeccpars2_439_(__Stack0) ->
+ [__1 | __Stack] = __Stack0,
[begin
- { remote , ? line ( __2 ) , __1 , __3 }
+ [ __1 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9133).
--compile({inline,yeccpars2_429_/1}).
--file("erl_parse.yrl", 250).
-yeccpars2_429_(__Stack0) ->
+-compile({inline,yeccpars2_442_/1}).
+-file("erl_parse.yrl", 97).
+yeccpars2_442_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record_field , ? line ( __2 ) , __1 , __3 }
+ { typed , __1 , __3 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9142).
--compile({inline,yeccpars2_432_/1}).
--file("erl_parse.yrl", 336).
-yeccpars2_432_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_443_/1}).
+-file("erl_parse.yrl", 94).
+yeccpars2_443_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __4 }
+ [ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9151).
--compile({inline,yeccpars2_434_/1}).
--file("erl_parse.yrl", 334).
-yeccpars2_434_(__Stack0) ->
- [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_445_/1}).
+-file("erl_parse.yrl", 93).
+yeccpars2_445_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- { record_field , ? line ( __2 ) , __1 , element ( 3 , __3 ) , __5 }
+ [ __1 | __3 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9160).
--compile({inline,yeccpars2_435_/1}).
--file("erl_parse.yrl", 236).
-yeccpars2_435_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_446_/1}).
+-file("erl_parse.yrl", 95).
+yeccpars2_446_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- ? mkop1 ( __1 , __2 )
+ [ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_436_/1}).
--file("erl_parse.yrl", 201).
-yeccpars2_436_(__Stack0) ->
- [begin
- [ ]
- end | __Stack0].
-
--compile({inline,yeccpars2_437_/1}).
--file("erl_parse.yrl", 198).
-yeccpars2_437_(__Stack0) ->
- [__1 | __Stack] = __Stack0,
+-file("/ldisk/pan/git/otp/bootstrap/lib/stdlib/egen/erl_parse.erl", 9336).
+-compile({inline,yeccpars2_447_/1}).
+-file("erl_parse.yrl", 90).
+yeccpars2_447_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- element ( 1 , __1 )
+ { tuple , ? line ( __1 ) , __2 }
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9184).
--compile({inline,yeccpars2_439_/1}).
--file("erl_parse.yrl", 481).
-yeccpars2_439_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_448_/1}).
+-file("erl_parse.yrl", 195).
+yeccpars2_448_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 }
+ [ __2 | __4 ]
end | __Stack].
--file("/clearcase/otp/erts/bootstrap/lib/stdlib/egen/erl_parse.erl", 9193).
--compile({inline,yeccpars2_440_/1}).
--file("erl_parse.yrl", 195).
-yeccpars2_440_(__Stack0) ->
- [__4,__3,__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_449_/1}).
+-file("erl_parse.yrl", 74).
+yeccpars2_449_(__Stack0) ->
+ [__5,__4,__3,__2,__1 | __Stack] = __Stack0,
[begin
- { clause , ? line ( __1 ) , element ( 3 , __1 ) , __2 , __3 , __4 }
+ build_typed_attribute ( __2 , __4 )
end | __Stack].
--compile({inline,yeccpars2_442_/1}).
--file("erl_parse.yrl", 483).
-yeccpars2_442_(__Stack0) ->
- [__2,__1 | __Stack] = __Stack0,
+-compile({inline,yeccpars2_451_/1}).
+-file("erl_parse.yrl", 194).
+yeccpars2_451_(__Stack0) ->
+ [__3,__2,__1 | __Stack] = __Stack0,
[begin
- __2
+ [ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_443_/1}).
+-compile({inline,yeccpars2_452_/1}).
-file("erl_parse.yrl", 68).
-yeccpars2_443_(__Stack0) ->
+yeccpars2_452_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
__1
end | __Stack].
--compile({inline,yeccpars2_444_/1}).
+-compile({inline,yeccpars2_453_/1}).
-file("erl_parse.yrl", 69).
-yeccpars2_444_(__Stack0) ->
+yeccpars2_453_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
__1
end | __Stack].
--compile({inline,yeccpars2_446_/1}).
--file("erl_parse.yrl", 192).
-yeccpars2_446_(__Stack0) ->
+-compile({inline,yeccpars2_455_/1}).
+-file("erl_parse.yrl", 200).
+yeccpars2_455_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_448_/1}).
--file("erl_parse.yrl", 201).
-yeccpars2_448_(__Stack0) ->
+-compile({inline,yeccpars2_457_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_457_(__Stack0) ->
[begin
[ ]
end | __Stack0].
--compile({inline,yeccpars2_450_/1}).
+-compile({inline,yeccpars2_459_/1}).
-file("erl_parse.yrl", 70).
-yeccpars2_450_(__Stack0) ->
+yeccpars2_459_(__Stack0) ->
[__2,__1 | __Stack] = __Stack0,
[begin
__1
end | __Stack].
--compile({inline,yeccpars2_452_/1}).
--file("erl_parse.yrl", 478).
-yeccpars2_452_(__Stack0) ->
+-compile({inline,yeccpars2_461_/1}).
+-file("erl_parse.yrl", 490).
+yeccpars2_461_(__Stack0) ->
[__3,__2,__1 | __Stack] = __Stack0,
[begin
[ __1 | __3 ]
end | __Stack].
--compile({inline,yeccpars2_454_/1}).
--file("erl_parse.yrl", 201).
-yeccpars2_454_(__Stack0) ->
+-compile({inline,yeccpars2_463_/1}).
+-file("erl_parse.yrl", 209).
+yeccpars2_463_(__Stack0) ->
[begin
[ ]
end | __Stack0].
--file("erl_parse.yrl", 1034).
+-file("erl_parse.yrl", 1057).
diff --git a/erts/aclocal.m4 b/erts/aclocal.m4
index 3d935b7295..61244c7cd3 100644
--- a/erts/aclocal.m4
+++ b/erts/aclocal.m4
@@ -512,6 +512,8 @@ dnl
AC_DEFUN(LM_CHECK_THR_LIB,
[
+NEED_NPTL_PTHREAD_H=no
+
dnl win32?
AC_MSG_CHECKING([for native win32 threads])
if test "X$host_os" = "Xwin32"; then
@@ -585,7 +587,9 @@ dnl On ofs1 the '-pthread' switch should be used
fi
if test $nptl = yes; then
need_nptl_incldir=no
- AC_CHECK_HEADER(nptl/pthread.h, need_nptl_incldir=yes)
+ AC_CHECK_HEADER(nptl/pthread.h,
+ [need_nptl_incldir=yes
+ NEED_NPTL_PTHREAD_H=yes])
if test $need_nptl_incldir = yes; then
# Ahh...
nptl_path="$C_INCLUDE_PATH:$CPATH"
@@ -799,6 +803,11 @@ case "$THR_LIB_NAME" in
AC_DEFINE(ETHR_HAVE_MIT_PTHREAD_H, 1, \
[Define if the pthread.h header file is in pthread/mit directory.]))
+ if test $NEED_NPTL_PTHREAD_H = yes; then
+ AC_DEFINE(ETHR_NEED_NPTL_PTHREAD_H, 1, \
+[Define if you need the <nptl/pthread.h> header file.])
+ fi
+
AC_CHECK_HEADER(sys/time.h, \
AC_DEFINE(ETHR_HAVE_SYS_TIME_H, 1, \
[Define if you have the <sys/time.h> header file.]))
@@ -826,23 +835,70 @@ case "$THR_LIB_NAME" in
AC_CHECK_FUNC(pthread_spin_lock, \
AC_DEFINE(ETHR_HAVE_PTHREAD_SPIN_LOCK, 1, \
[Define if you have the pthread_spin_lock function.]))
- 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
- ;;
- *)
- AC_CHECK_FUNC(pthread_rwlock_init, \
- AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_INIT, 1, \
-[Define if you have a pthread_rwlock implementation that can be used.]))
- ;;
- esac
+
+ have_pthread_rwlock_init=no
+ AC_CHECK_FUNC(pthread_rwlock_init, [have_pthread_rwlock_init=yes])
+ if test $have_pthread_rwlock_init = yes; then
+
+ AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_INIT, 1, \
+[Define if you have a pthread_rwlock implementation that can be used.])
+
+ ethr_have_pthread_rwlockattr_setkind_np=no
+ AC_CHECK_FUNC(pthread_rwlockattr_setkind_np,
+ [ethr_have_pthread_rwlockattr_setkind_np=yes])
+
+ if test $ethr_have_pthread_rwlockattr_setkind_np = yes; then
+ AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP, 1, \
+[Define if you have the pthread_rwlockattr_setkind_np() function.])
+
+ AC_MSG_CHECKING([for PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP])
+ ethr_pthread_rwlock_writer_nonrecursive_initializer_np=no
+ AC_TRY_LINK([
+ #if defined(ETHR_NEED_NPTL_PTHREAD_H)
+ #include <nptl/pthread.h>
+ #elif defined(ETHR_HAVE_MIT_PTHREAD_H)
+ #include <pthread/mit/pthread.h>
+ #elif defined(ETHR_HAVE_PTHREAD_H)
+ #include <pthread.h>
+ #endif
+ ],
+ [
+ pthread_rwlockattr_t *attr;
+ return pthread_rwlockattr_setkind_np(attr,
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
+ ],
+ [ethr_pthread_rwlock_writer_nonrecursive_initializer_np=yes])
+ AC_MSG_RESULT([$ethr_pthread_rwlock_writer_nonrecursive_initializer_np])
+ if test $ethr_pthread_rwlock_writer_nonrecursive_initializer_np = yes; then
+ AC_DEFINE(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP, 1, \
+[Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock attribute.])
+ fi
+ fi
+ fi
+
+
+
AC_CHECK_FUNC(pthread_attr_setguardsize, \
AC_DEFINE(ETHR_HAVE_PTHREAD_ATTR_SETGUARDSIZE, 1, \
[Define if you have the pthread_attr_setguardsize function.]))
+ AC_MSG_CHECKING([for GCC atomic operations])
+ ethr_have_gcc_atomic_ops=no
+ AC_TRY_LINK([],
+ [
+ long res;
+ volatile long val;
+ res = __sync_val_compare_and_swap(&val, (long) 1, (long) 0);
+ res = __sync_add_and_fetch(&val, (long) 1);
+ res = __sync_sub_and_fetch(&val, (long) 1);
+ res = __sync_fetch_and_and(&val, (long) 1);
+ res = __sync_fetch_and_or(&val, (long) 1);
+ ],
+ [ethr_have_native_atomics=yes
+ ethr_have_gcc_atomic_ops=yes])
+ AC_MSG_RESULT([$ethr_have_gcc_atomic_ops])
+ test $ethr_have_gcc_atomic_ops = yes && AC_DEFINE(ETHR_HAVE_GCC_ATOMIC_OPS, 1, [Define if you have gcc atomic operations])
+
dnl Restore LIBS
LIBS=$saved_libs
dnl restore CPPFLAGS
@@ -873,6 +929,17 @@ if test "X$disable_native_ethr_impls" = "Xyes"; then
AC_DEFINE(ETHR_DISABLE_NATIVE_IMPLS, 1, [Define if you want to disable native ethread implementations])
fi
+AC_ARG_ENABLE(prefer-gcc-native-ethr-impls,
+ AS_HELP_STRING([--enable-prefer-gcc-native-ethr-impls],
+ [enable prefer gcc native ethread implementations]),
+[ case "$enableval" in
+ yes) enable_prefer_gcc_native_ethr_impls=yes ;;
+ *) enable_prefer_gcc_native_ethr_impls=no ;;
+ esac ], enable_prefer_gcc_native_ethr_impls=no)
+
+test $enable_prefer_gcc_native_ethr_impls = yes &&
+ AC_DEFINE(ETHR_PREFER_GCC_NATIVE_IMPLS, 1, [Define if you prefer gcc native ethread implementations])
+
AC_DEFINE(ETHR_HAVE_ETHREAD_DEFINES, 1, \
[Define if you have all ethread defines])
diff --git a/erts/configure.in b/erts/configure.in
index a14b10adbf..63bf548c89 100644
--- a/erts/configure.in
+++ b/erts/configure.in
@@ -1054,6 +1054,7 @@ fi
AC_SUBST(ERTS_BUILD_SMP_EMU)
+AC_CHECK_FUNCS([posix_fadvise])
#
@@ -1757,6 +1758,12 @@ fi
dnl Need by run_erl.
AC_CHECK_FUNCS([openpty])
+dnl fdatasync syscall (Unix only)
+AC_CHECK_FUNCS([fdatasync])
+
+dnl Find which C libraries are required to use fdatasync
+AC_SEARCH_LIBS(fdatasync, [rt])
+
dnl ----------------------------------------------------------------------
dnl Checks for features/quirks in the system that affects Erlang.
dnl ----------------------------------------------------------------------
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index bb741c7836..df80142ce1 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -41,6 +41,26 @@
to scroll back to text which has scrolled off the screen.
The <c><![CDATA[erl]]></c> program must be used, however, in pipelines or if
you want to redirect standard input or output.</p>
+ <note><p>As of ERTS version 5.8 (OTP-R14A) the runtime system will by
+ default bind schedulers to logical processors using the
+ <c>default_bind</c> bind type if the amount of schedulers are
+ at least equal to the amount of logical processors configured,
+ binding of schedulers is supported, and a CPU topology is
+ available at startup.
+ </p><p>
+ If the Erlang runtime system is the only operating system
+ process that binds threads to logical processors, this
+ improves the performance of the runtime system. However,
+ if other operating system processes (as for example
+ another Erlang runtime system) also bind threads to
+ logical processors, there might be a performance penalty
+ instead. If this is the case you, are are advised to
+ unbind the schedulers using the
+ <seealso marker="#+sbt">+sbtu</seealso> command line argument,
+ or by invoking
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type,
+ unbound)</seealso>.</p>
+ </note>
</description>
<funcs>
<func>
@@ -657,6 +677,22 @@
that the <c>+sct</c> flag may have to be passed before the
<c>+sbt</c> flag on the command line (in case no CPU topology
has been automatically detected).</p>
+ <p>The runtime system will by default bind schedulers to logical
+ processors using the <c>default_bind</c> bind type if the amount
+ of schedulers are at least equal to the amount of logical
+ processors configured, binding of schedulers is supported,
+ and a CPU topology is available at startup.
+ </p>
+ <p><em>NOTE:</em> If the Erlang runtime system is the only operating
+ system process that binds threads to logical processors, this
+ improves the performance of the runtime system. However, if other
+ operating system processes (as for example another Erlang runtime
+ system) also bind threads to logical processors, there might be a
+ performance penalty instead. If this is the case you, are advised
+ to unbind the schedulers using the <c>+sbtu</c> command line
+ argument, or by invoking
+ <seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type,
+ unbound)</seealso>.</p>
<p>For more information, see
<seealso marker="erlang#system_flag_scheduler_bind_type">erlang:system_flag(scheduler_bind_type, SchedulerBindType)</seealso>.
</p>
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml
index 5ec844e2ad..f7b7b2f346 100644
--- a/erts/doc/src/erl_nif.xml
+++ b/erts/doc/src/erl_nif.xml
@@ -38,6 +38,18 @@
EXPERIMENTAL feature. The interfaces may be changed in any way
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>R14A</em>:</p>
+ <list>
+ <item>Environment argument removed for <c>enif_alloc</c>,
+ <c>enif_realloc</c>, <c>enif_free</c>, <c>enif_alloc_binary</c>,
+ <c>enif_realloc_binary</c>, <c>enif_release_binary</c>,
+ <c>enif_alloc_resource</c>, <c>enif_release_resource</c>,
+ <c>enif_is_identical</c> and <c>enif_compare</c>.</item>
+ <item>Character encoding argument added to <c>enif_get_atom</c>
+ and <c>enif_make_existing_atom</c>.</item>
+ <item>Module argument added to <c>enif_open_resource_type</c>
+ while changing name spaces of resource types from global to module local.</item>
+ </list>
<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>
@@ -109,9 +121,9 @@ ok
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 NIF does not have to be exported, it can be local to the module.
+ Note however that unused local stub functions 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
@@ -122,7 +134,7 @@ ok
will be shared as well. To avoid unintentionally shared static
data, each Erlang module code can keep its own private data. This
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>
+ 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
@@ -137,14 +149,20 @@ ok
<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>
+ be returned as function return values. The terms are of C-type
+ <seealso marker="#ERL_NIF_TERM">ERL_NIF_TERM</seealso>
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>
+ <c>enif_compare</c>.</p>
+ <p>All terms of type <c>ERL_NIF_TERM</c> belong to an environment of type
+ <seealso marker="#ErlNifEnv">ErlNifEnv</seealso>. The lifetime of a term is
+ controlled by the lifetime of its environment object. All API functions that read
+ or write terms has the environment, that the term belongs to, as the first
+ function argument.</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>
@@ -172,28 +190,29 @@ ok
<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>.
+ <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>.
+ <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>
+ 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>
+ 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>
+ <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>
+ are uniquely identified by a supplied name string and the name of the
+ implementing module.</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
@@ -208,7 +227,7 @@ ok
<p/>
<code type="none">
ERL_NIF_TERM term;
- MyStruct* ptr = enif_alloc_resource(env, my_resource_type, sizeof(MyStruct));
+ MyStruct* ptr = enif_alloc_resource(my_resource_type, sizeof(MyStruct));
/* initialize struct ... */
@@ -218,21 +237,31 @@ ok
/* store 'ptr' in static variable, private data or other resource object */
}
else {
- enif_release_resource(env, obj);
+ enif_release_resource(obj);
/* resource now only owned by "Erlang" */
}
return term;
}
</code>
-
+ <p>Another usage of resource objects is to create binary terms with
+ user defined memory management.
+ <seealso marker="#enif_make_resource_binary">enif_make_resource_binary</seealso>
+ will create a binary term that is connected to a resource object. The
+ destructor of the resource will be called when the binary is garbage
+ collected, at which time the binary data can be released. An example of
+ this can be a binary term consisting of data from a <c>mmap</c>'ed file.
+ The destructor can then do <c>munmap</c> to release the memory
+ region.</p>
</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>
+ you need to supply your own explicit synchronization. This includes terms
+ in process independent environments that are shared between threads.
+ 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
@@ -265,7 +294,7 @@ 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 order to keep a state between NIF
- calls. <c>enif_priv_data()</c> will return this pointer.
+ 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
@@ -317,19 +346,37 @@ ok
<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>
+ arguments to API functions or as return values from NIFs. All
+ <c>ERL_NIF_TERM</c>'s belong to an environment
+ (<seealso marker="#ErlNifEnv">ErlNifEnv</seealso>). A term can not be
+ destructed individually, it is valid until its environment is destructed.</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
- dereferenced in any way, but only passed on to API
- functions. An <c>ErlNifEnv</c> pointer is only valid until
- the function, where it was supplied as argument,
- returns. It is thus useless and dangerous to store <c>ErlNifEnv</c>
- pointers in between NIF calls.</p>
+ <p><c>ErlNifEnv</c> represents an environment that can host Erlang terms.
+ All terms in an environment are valid as long as the environment is valid.
+ <c>ErlNifEnv</c> is an opaque type and pointers to it can only be passed
+ on to API functions. There are two types of environments; process
+ bound and process independent.</p>
+ <p>A <em>process bound environment</em> is passed as the first argument to all NIFs.
+ All function arguments passed to a NIF will belong to that environment.
+ The return value from a NIF must also be a term belonging to the same
+ environment.
+ In addition a process bound environment contains transient information
+ about the calling Erlang process. The environment is only valid in the
+ thread where it was supplied as argument until the NIF returns. It is
+ thus useless and dangerous to store pointers to process bound
+ environments between NIF calls. </p>
+ <p>A <em>process independent environment</em> is created by calling
+ <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>. It can be
+ used to store terms beteen NIF calls and to send terms with
+ <seealso marker="#enif_send">enif_send</seealso>. A process
+ independent environment with all its terms is valid until you explicitly
+ invalidates it with <seealso marker="#enif_free_env">enif_free_env</seealso>
+ or <c>enif_send</c>.</p>
+ <p>All elements of a list/tuple must belong to the same environment as the
+ list/tuple itself. Terms can be copied between environments with
+ <seealso marker="#enif_make_copy">enif_make_copy</seealso>.</p>
</item>
<tag><marker id="ErlNifFunc"/>ErlNifFunc</tag>
<item>
@@ -363,7 +410,18 @@ typedef struct {
<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>
+ <p>Note that <c>ErlNifBinary</c> is a semi-opaque type and you are
+ only allowed to read fields <c>size</c> and <c>data</c>.</p>
</item>
+ <tag><marker id="ErlNifPid"/>ErlNifPid</tag>
+ <item>
+ <p><c>ErlNifPid</c> is a process identifier (pid). In contrast to
+ pid terms (instances of <c>ERL_NIF_TERM</c>), <c>ErlNifPid</c>'s are self
+ contained and not bound to any
+ <seealso marker="#ErlNifEnv">environment</seealso>. <c>ErlNifPid</c>
+ is an opaque type.</p>
+ </item>
+
<tag><marker id="ErlNifResourceType"/>ErlNifResourceType</tag>
<item>
<p>Each instance of <c>ErlNifResourceType</c> represent a class of
@@ -388,9 +446,9 @@ 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>
+ <p>The character encoding used in strings and atoms. 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>
@@ -407,24 +465,40 @@ typedef enum {
<fsummary>Allocate dynamic memory.</fsummary>
<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>
+ <func><name><ret>int</ret><nametext>enif_alloc_binary(size_t size, ErlNifBinary* bin)</nametext></name>
<fsummary>Create a new binary.</fsummary>
<desc><p>Allocate a new binary of size <c>size</c>
bytes. Initialize the structure pointed to by <c>bin</c> to
refer to the allocated binary. The binary must either be released by
- <seealso marker="#enif_release_binary">enif_release_binary()</seealso>
+ <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>.
+ <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>
+ <p>Return true on success or false if allocation failed.</p>
+ </desc>
+ </func>
+ <func><name><ret>ErlNifEnv*</ret><nametext>enif_alloc_env()</nametext></name>
+ <fsummary>Create a new environment</fsummary>
+ <desc><p>Allocate a new process independent environment. The environment can
+ be used to hold terms that is not bound to any process. Such terms can
+ later be copied to a process environment with
+ <seealso marker="#enif_make_copy">enif_make_copy</seealso>
+ or be sent to a process as a message with <seealso marker="#enif_send">enif_send</seealso>.</p>
+ <p>Return pointer to the new environment.</p>
</desc>
</func>
- <func><name><ret>void*</ret><nametext>enif_alloc_resource(ErlNifEnv* env, ErlNifResourceType* type, unsigned size)</nametext></name>
+ <func><name><ret>void*</ret><nametext>enif_alloc_resource(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>
+ <func><name><ret>void</ret><nametext>enif_clear_env(ErlNifEnv* env)</nametext></name>
+ <fsummary>Clear an environment for reuse.</fsummary>
+ <desc><p>Free all terms in an environment and clear it for reuse. The environment must
+ have been allocated with <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>.
+ </p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_compare(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,
@@ -434,77 +508,98 @@ typedef enum {
</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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>
+ <func><name><ret>void</ret><nametext>enif_free_env(ErlNifEnv* env)</nametext></name>
+ <fsummary>Free an environment allocated with enif_alloc_env</fsummary>
+ <desc><p>Free an environment allocated with <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>.
+ All terms created in the environment will be freed as well.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_atom(ErlNifEnv* env, ERL_NIF_TERM term, char* buf, unsigned size, ErlNifCharEncoding encode)</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
+ representation of the atom <c>term</c> with encoding
+ <seealso marker="#ErlNifCharEncoding">encode</seealso>. 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_atom_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len, ErlNifCharEncoding encode)</nametext></name>
+ <fsummary>Get the length of atom <c>term</c>.</fsummary>
+ <desc><p>Set <c>*len</c> to the length (number of bytes excluding
+ terminating null character) of the atom <c>term</c> with encoding
+ <c>encode</c>. Return true on success or false if <c>term</c> is not an
+ atom.</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>
+ <c>term</c>. Return true on success or 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>
+ <fsummary>Read an integer term</fsummary>
<desc><p>Set <c>*ip</c> to the 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>int</c></p></desc>
+ <c>term</c>. Return true on success or 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_local_pid(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPid* pid)</nametext></name>
+ <fsummary>Read an local pid term</fsummary>
+ <desc><p>If <c>term</c> is the pid of a node local process, initialize the
+ pid variable <c>*pid</c> from it and return true. Otherwise return false.
+ No check if the process is alive is done.</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>
+ <c>list</c> and return true, or return false if <c>list</c> is not a
+ non-empty list.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_get_list_length(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len)</nametext></name>
+ <fsummary>Get the length of list <c>term</c>.</fsummary>
+ <desc><p>Set <c>*len</c> to the length of list <c>term</c> and return true,
+ or return false if <c>term</c> is not a list.</p></desc>
</func>
<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
+ <desc><p>Set <c>*ip</c> to the long integer value of <c>term</c> and
+ return true, 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>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
+ <desc><p>Set <c>*objp</c> to point to the resource object referred to by <c>term</c>.</p>
+ <p>Return true on success or false if <c>term</c> is not a handle to a resource object
of type <c>type</c>.</p></desc>
</func>
<func><name><ret>int</ret><nametext>enif_get_string(ErlNifEnv* env,
@@ -529,27 +624,27 @@ typedef enum {
<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
+ is zero.</p><p>Return true on success or 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>
+ <desc><p>Set <c>*ip</c> to the unsigned integer value of <c>term</c> and
+ return true, 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>
+ <desc><p>Set <c>*ip</c> to the unsigned long integer value of <c>term</c>
+ and return true, 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>
+ <c>bin_term</c>. Return true on success or 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)
@@ -558,7 +653,7 @@ typedef enum {
<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
+ not need to be released. Return true on success or false if <c>iolist</c> is not an
iolist.</p>
</desc>
</func>
@@ -578,7 +673,7 @@ typedef enum {
<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>
+ <func><name><ret>int</ret><nametext>enif_is_identical(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
@@ -592,15 +687,35 @@ typedef enum {
<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>int</ret><nametext>enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a tuple</fsummary>
+ <desc><p>Return true if <c>term</c> is a tuple.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term)</nametext></name>
+ <fsummary>Determine if a term is a list</fsummary>
+ <desc><p>Return true if <c>term</c> is a list.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_keep_resource(void* obj)</nametext></name>
+ <fsummary>Add a reference to a resource object</fsummary>
+ <desc><p>Add a reference to resource object <c>obj</c> obtained from
+ <seealso marker="#enif_alloc_resource">enif_alloc_resource</seealso>.
+ Each call to <c>enif_keep_resource</c> for an object must be balanced by
+ a call to <seealso marker="#enif_release_resource">enif_release_resource</seealso>
+ before the object will be destructed.</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>. Unlike other terms, atom
- terms may be saved and used between NIF calls.</p></desc>
+ <desc><p>Create an atom term from the null-terminated C-string <c>name</c>
+ with iso-latin-1 encoding.</p></desc>
+ </func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)</nametext></name>
+ <fsummary>Create an atom term</fsummary>
+ <desc><p>Create an atom term from the string <c>name</c> with length <c>len</c>.
+ Null-characters are treated as any other characters.</p></desc>
</func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_badarg(ErlNifEnv* env)</nametext></name>
<fsummary>Make a badarg exception.</fsummary>
@@ -613,16 +728,31 @@ typedef enum {
<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_copy(ErlNifEnv* dst_env, ERL_NIF_TERM src_term)</nametext></name>
+ <fsummary>Make a copy of a term.</fsummary>
+ <desc><p>Make a copy of term <c>src_term</c>. The copy will be created in
+ environment <c>dst_env</c>. The source term may be located in any
+ environment.</p></desc>
+ </func>
<func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_double(ErlNifEnv* env, double d)</nametext></name>
<fsummary>Create a floating-point term</fsummary>
<desc><p>Create a 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>
+ <func><name><ret>int</ret><nametext>enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding encode)</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>
+ the null-terminated C-string <c>name</c> with encoding
+ <seealso marker="#ErlNifCharEncoding">encode</seealso>. If the atom
+ already exists store the term in <c>*atom</c> and return true, otherwise
+ return false.</p></desc>
+ </func>
+ <func><name><ret>int</ret><nametext>enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)</nametext></name>
+ <fsummary>Create an existing atom term</fsummary>
+ <desc><p>Try to create the term of an already existing atom from the
+ string <c>name</c> with length <c>len</c> and encoding
+ <seealso marker="#ErlNifCharEncoding">encode</seealso>. Null-characters
+ are treated as any other characters. If the atom already exists 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>
@@ -662,7 +792,7 @@ typedef enum {
<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>unsigned char*</ret><nametext>enif_make_new_binary(ErlNifEnv* env, unsigned size, ERL_NIF_TERM* termp)</nametext></name>
+ <func><name><ret>unsigned char*</ret><nametext>enif_make_new_binary(ErlNifEnv* env, size_t size, ERL_NIF_TERM* termp)</nametext></name>
<fsummary>Allocate and create a new binary term</fsummary>
<desc><p>Allocate a binary of size <c>size</c> bytes and create an owning
term. The binary data is mutable until the calling NIF returns. This is a
@@ -672,6 +802,10 @@ typedef enum {
reallocated.</p><p>Return a pointer to the raw binary data and set
<c>*termp</c> to the binary term.</p></desc>
</func>
+ <func><name><ret>ERL_NIF_TERM</ret><nametext>enif_make_pid(ErlNifEnv* env, const ErlNifPid* pid)</nametext></name>
+ <fsummary>Make a pid term</fsummary>
+ <desc><p>Make a pid term from <c>*pid</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>
@@ -687,13 +821,42 @@ typedef enum {
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_resource_binary(ErlNifEnv* env, void* obj, const void* data, size_t size)</nametext></name>
+ <fsummary>Create a custom binary term</fsummary>
+ <desc><p>Create a binary term that is memory managed by a resource object
+ <c>obj</c> obtained by <seealso marker="#enif_alloc_resource">enif_alloc_resource</seealso>.
+ The returned binary term will consist of <c>size</c> bytes pointed to
+ by <c>data</c>. This raw binary data must be kept readable and unchanged
+ until the destructor of the resource is called. The binary data may be
+ stored external to the resource object in which case it is the responsibility
+ of the destructor to release the data.</p>
+ <p>Several binary terms may be managed by the same resource object. The
+ destructor will not be called until the last binary is garbage collected.
+ This can be useful as a way to return different parts of a larger binary
+ buffer.</p>
+ <p>As with <seealso marker="#enif_make_resource">enif_make_resource</seealso>,
+ no ownership transfer is done. The resource still needs to be released with
+ <seealso marker="#enif_release_resource">enif_release_resource</seealso>.</p>
+ </desc>
+ </func>
+ <func><name><ret>ErlNifPid*</ret><nametext>enif_self(ErlNifEnv* caller_env, ErlNifPid* pid)</nametext></name>
+ <fsummary>Get the pid of the calling process.</fsummary>
+ <desc><p>Initialize the pid variable <c>*pid</c> to represent the
+ calling process. Return <c>pid</c>.</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>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_string_len(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding encoding)</nametext></name>
+ <fsummary>Create a string.</fsummary>
+ <desc><p>Create a list containing the characters of the string <c>string</c> with
+ length <c>len</c> and encoding <seealso marker="#ErlNifCharEncoding">encoding</seealso>.
+ Null-characters are treated as any other characters.</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>
+ env, ERL_NIF_TERM bin_term, size_t pos, size_t 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.
@@ -737,30 +900,31 @@ typedef enum {
</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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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,
+ <func><name><ret>ErlNifResourceType*</ret><nametext>enif_open_resource_type(ErlNifEnv* env,
+ const char* module_str, 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
@@ -774,10 +938,10 @@ typedef enum {
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 unintentional
- 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>The two flag values can be combined with bitwise-or. The name of the
+ resource type is local to the calling module. Argument <c>module_str</c>
+ is not (yet) used and must be NULL. 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.
@@ -794,123 +958,151 @@ typedef enum {
<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>
+ <func><name><ret>void</ret><nametext>enif_realloc_binary(ErlNifBinary* bin, size_t 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>
+ <func><name><ret>void</ret><nametext>enif_release_binary(ErlNifBinary* bin)</nametext></name>
<fsummary>Release a binary.</fsummary>
- <desc><p>Release a binary obtained
- from <c>enif_alloc_binary</c>.</p></desc>
+ <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>
+ <func><name><ret>void</ret><nametext>enif_release_resource(void* obj)</nametext></name>
<fsummary>Release a resource object.</fsummary>
- <desc><p>Release a resource object 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>
+ <desc><p>Remove a reference to resource object <c>obj</c>obtained from
+ <seealso marker="#enif_alloc_resource">enif_alloc_resource</seealso>.
+ The resource object will be destructed when the last reference is removed.
+ Each call to <c>enif_release_resource</c> must correspond to a previous
+ call to <c>enif_alloc_resource</c> or
+ <seealso marker="#enif_keep_resource">enif_keep_resource</seealso>.
+ References made by <seealso marker="#enif_make_resource">enif_make_resource</seealso>
+ can only be removed 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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>
+ <func><name><ret>unsigned</ret><nametext>enif_send(ErlNifEnv* env, ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg)</nametext></name>
+ <fsummary>Send a message to a process.</fsummary>
+ <desc><p>Send a message to a process.</p>
+ <taglist>
+ <tag><c>env</c></tag>
+ <item>The environment of the calling process. Must be NULL if and
+ only if calling from a created thread.</item>
+ <tag><c>*to_pid</c></tag>
+ <item>The pid of the receiving process. The pid should refer to a process on the local node.</item>
+ <tag><c>msg_env</c></tag>
+ <item>The environment of the message term. Must be a process
+ independent environment allocated with
+ <seealso marker="#enif_alloc_env">enif_alloc_env</seealso>.</item>
+ <tag><c>msg</c></tag>
+ <item>The message term to send.</item>
+ </taglist>
+ <p>Return true on success, or false if <c>*to_pid</c> does not refer to an alive local process.</p>
+ <p>The message environment <c>msg_env</c> with all its terms (including
+ <c>msg</c>) will be invalidated by a successful call to <c>enif_send</c>. The environment
+ should either be freed with <seealso marker="#enif_free_env">enif_free_env</seealso>
+ of cleared for reuse with <seealso marker="#enif_clear_env">enif_clear_env</seealso>.</p>
+ <p>This function is only thread-safe when the emulator with SMP support is used.
+ It can only be used in a non-SMP emulator from a NIF-calling thread.</p>
+ </desc>
+ </func>
+ <func><name><ret>unsigned</ret><nametext>enif_sizeof_resource(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>
+ <seealso marker="#enif_alloc_resource">enif_alloc_resource</seealso>.</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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <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>.
+ <desc><p>Same as <seealso marker="erl_driver#erl_drv_tsd_set">erl_drv_tsd_set</seealso>.
</p></desc>
</func>
</funcs>
diff --git a/erts/doc/src/erlang.xml b/erts/doc/src/erlang.xml
index cd9bb85f5c..c8fe7b4bd2 100644
--- a/erts/doc/src/erlang.xml
+++ b/erts/doc/src/erlang.xml
@@ -253,6 +253,54 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
+ <name>binary_part(Subject, PosLen) -> binary()</name>
+ <fsummary>Extracts a part of a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>PosLen = {Start,Length}</v>
+ <v>Start = int()</v>
+ <v>Length = int()</v>
+ </type>
+ <desc>
+ <p>Extracts the part of the binary described by <c>PosLen</c>.</p>
+
+ <p>Negative length can be used to extract bytes at the end of a binary:</p>
+
+<code>
+1> Bin = &lt;&lt;1,2,3,4,5,6,7,8,9,10&gt;&gt;.
+2> binary_part(Bin,{byte_size(Bin), -5)).
+&lt;&lt;6,7,8,9,10&gt;&gt;
+</code>
+
+ <p>If <c>PosLen</c> in any way references outside the binary, a <c>badarg</c> exception is raised.</p>
+
+ <p><c>Start</c> is zero-based, i.e:</p>
+<code>
+1> Bin = &lt;&lt;1,2,3&gt;&gt;
+2> binary_part(Bin,{0,2}).
+&lt;&lt;1,2&gt;&gt;
+</code>
+
+ <p>See the STDLIB module <c>binary</c> for details about the <c>PosLen</c> semantics.</p>
+
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
+ <name>binary_part(Subject, Start, Length) -> binary()</name>
+ <fsummary>Extracts a part of a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Start = int()</v>
+ <v>Length = int()</v>
+ </type>
+ <desc>
+ <p>The same as <c>binary_part(Subject, {Pos, Len})</c>.</p>
+
+ <p>Allowed in guard tests.</p>
+ </desc>
+ </func>
+ <func>
<name>binary_to_atom(Binary, Encoding) -> atom()</name>
<fsummary>Convert from text representation to an atom</fsummary>
<type>
@@ -318,6 +366,11 @@ iolist() = [char() | binary() | iolist()]
corresponding to the bytes from position <c>Start</c> to
position <c>Stop</c> in <c>Binary</c>. Positions in the
binary are numbered starting from 1.</p>
+
+ <note><p>This function's indexing style of using one-based indices for
+ binaries is deprecated. New code should use the functions in
+ the STDLIB module <c>binary</c> instead. They consequently
+ use the same (zero-based) style of indexing.</p></note>
</desc>
</func>
<func>
@@ -354,7 +407,7 @@ iolist() = [char() | binary() | iolist()]
</desc>
</func>
<func>
- <name>erlang:binary_to_term(Binary, Opts) -> term()</name>
+ <name>binary_to_term(Binary, Opts) -> term()</name>
<fsummary>Decode an Erlang external term format binary</fsummary>
<type>
<v>Opts = [safe]</v>
@@ -5103,10 +5156,21 @@ true</pre>
For more information on how to define the CPU topology, see
<seealso marker="#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>.
</p>
- <p><em>NOTE:</em> If other programs on the system have bound
- to processors, e.g. another Erlang runtime system, you
- may lose performance when binding schedulers. Therefore,
- schedulers are by default not bound.</p>
+ <p>The runtime system will by default bind schedulers to logical
+ processors using the <c>default_bind</c> bind type if the amount
+ of schedulers are at least equal to the amount of logical
+ processors configured, binding of schedulers is supported,
+ and a CPU topology is available at startup.
+ </p>
+ <p><em>NOTE:</em> If the Erlang runtime system is the only
+ operating system process that binds threads to logical processors,
+ this improves the performance of the runtime system. However,
+ if other operating system processes (as for example another Erlang
+ runtime system) also bind threads to logical processors, there
+ might be a performance penalty instead. If this is the case you,
+ are are advised to unbind the schedulers using the
+ <seealso marker="erl#+sbt">+sbtu</seealso> command line argument,
+ or <c>erlang:system_flag(scheduler_bind_type, unbound)</c>.</p>
<p>Schedulers can be bound in different ways. The <c>How</c>
argument determines how schedulers are bound. <c>How</c> can
currently be one of:</p>
diff --git a/erts/doc/src/match_spec.xml b/erts/doc/src/match_spec.xml
index b9f955e4db..f0390c9db8 100644
--- a/erts/doc/src/match_spec.xml
+++ b/erts/doc/src/match_spec.xml
@@ -60,7 +60,7 @@
<section>
<title>Grammar</title>
- <p>A match_spec can be described in this <em>informal</em> grammar:</p>
+ <p>A match_spec used in tracing can be described in this <em>informal</em> grammar:</p>
<list type="bulleted">
<item>MatchExpression ::= [ MatchFunction, ... ]
</item>
@@ -117,6 +117,52 @@
<c><![CDATA[display]]></c> | <c><![CDATA[caller]]></c> | <c><![CDATA[set_tcw]]></c> |
<c><![CDATA[silent]]></c></item>
</list>
+
+ <p>A match_spec used in ets can be described in this <em>informal</em> grammar:</p>
+ <list type="bulleted">
+ <item>MatchExpression ::= [ MatchFunction, ... ]
+ </item>
+ <item>MatchFunction ::= { MatchHead, MatchConditions, MatchBody }
+ </item>
+ <item>MatchHead ::= MatchVariable | <c><![CDATA['_']]></c> | { MatchHeadPart, ... }
+ </item>
+ <item>MatchHeadPart ::= term() | MatchVariable | <c><![CDATA['_']]></c></item>
+ <item>MatchVariable ::= '$&lt;number&gt;'
+ </item>
+ <item>MatchConditions ::= [ MatchCondition, ...] | <c><![CDATA[[]]]></c></item>
+ <item>MatchCondition ::= { GuardFunction } |
+ { GuardFunction, ConditionExpression, ... }
+ </item>
+ <item>BoolFunction ::= <c><![CDATA[is_atom]]></c> | <c><![CDATA[is_constant]]></c> |
+ <c><![CDATA[is_float]]></c> | <c><![CDATA[is_integer]]></c> | <c><![CDATA[is_list]]></c> |
+ <c><![CDATA[is_number]]></c> | <c><![CDATA[is_pid]]></c> | <c><![CDATA[is_port]]></c> |
+ <c><![CDATA[is_reference]]></c> | <c><![CDATA[is_tuple]]></c> | <c><![CDATA[is_binary]]></c> |
+ <c><![CDATA[is_function]]></c> | <c><![CDATA[is_record]]></c> | <c><![CDATA[is_seq_trace]]></c> |
+ <c><![CDATA['and']]></c> | <c><![CDATA['or']]></c> | <c><![CDATA['not']]></c> | <c><![CDATA['xor']]></c> |
+ <c><![CDATA[andalso]]></c> | <c><![CDATA[orelse]]></c></item>
+ <item>ConditionExpression ::= ExprMatchVariable | { GuardFunction } |
+ { GuardFunction, ConditionExpression, ... } | TermConstruct
+ </item>
+ <item>ExprMatchVariable ::= MatchVariable (bound in the MatchHead) |
+ <c><![CDATA['$_']]></c> | <c><![CDATA['$$']]></c></item>
+ <item>TermConstruct = {{}} | {{ ConditionExpression, ... }} |
+ <c><![CDATA[[]]]></c> | [ConditionExpression, ...] | NonCompositeTerm | Constant
+ </item>
+ <item>NonCompositeTerm ::= term() (not list or tuple)
+ </item>
+ <item>Constant ::= {<c><![CDATA[const]]></c>, term()}
+ </item>
+ <item>GuardFunction ::= BoolFunction | <c><![CDATA[abs]]></c> |
+ <c><![CDATA[element]]></c> | <c><![CDATA[hd]]></c> | <c><![CDATA[length]]></c> | <c><![CDATA[node]]></c> |
+ <c><![CDATA[round]]></c> | <c><![CDATA[size]]></c> | <c><![CDATA[tl]]></c> | <c><![CDATA[trunc]]></c> |
+ <c><![CDATA['+']]></c> | <c><![CDATA['-']]></c> | <c><![CDATA['*']]></c> | <c><![CDATA['div']]></c> |
+ <c><![CDATA['rem']]></c> | <c><![CDATA['band']]></c> | <c><![CDATA['bor']]></c> | <c><![CDATA['bxor']]></c> |
+ <c><![CDATA['bnot']]></c> | <c><![CDATA['bsl']]></c> | <c><![CDATA['bsr']]></c> | <c><![CDATA['>']]></c> |
+ <c><![CDATA['>=']]></c> | <c><![CDATA['<']]></c> | <c><![CDATA['=<']]></c> | <c><![CDATA['=:=']]></c> |
+ <c><![CDATA['==']]></c> | <c><![CDATA['=/=']]></c> | <c><![CDATA['/=']]></c> | <c><![CDATA[self]]></c> |
+ <c><![CDATA[get_tcw]]></c></item>
+ <item>MatchBody ::= [ ConditionExpression, ... ]</item>
+ </list>
</section>
<section>
@@ -453,8 +499,8 @@
<section>
<title>Differences between match specifications in ETS and tracing</title>
<p>ETS match specifications are there to produce a return
- value. Usually the expression contains one single
- <c><![CDATA[ActionTerm]]></c> which defines the return value without having
+ value. Usually the <c><![CDATA[MatchBody]]></c> contains one single
+ <c><![CDATA[ConditionExpression]]></c> which defines the return value without having
any side effects. Calls with side effects are not allowed in the
ETS context.</p>
<p>When tracing there is no return value to produce, the
@@ -530,7 +576,7 @@
the atom 'strider' and the tuple arity is 3 and return the whole
object.</p>
<code type="none"><![CDATA[
-[{{strider,'_'.'_'},
+[{{strider,'_','_'},
[],
['$_']}]
]]></code>
diff --git a/erts/emulator/Makefile.in b/erts/emulator/Makefile.in
index 9f10a0ffaa..eca6121a1e 100644
--- a/erts/emulator/Makefile.in
+++ b/erts/emulator/Makefile.in
@@ -341,7 +341,6 @@ ERLANG_OSTYPE = @ERLANG_OSTYPE@
ENABLE_ALLOC_TYPE_VARS += @ERLANG_OSTYPE@
-EMULATOR_EXECUTABLE_SAE = beam_evm$(TF_MARKER)
EMULATOR_EXECUTABLE_ELIB = beam.elib$(TF_MARKER)
ifeq ($(TARGET), win32)
EMULATOR_EXECUTABLE = beam$(TF_MARKER).dll
@@ -406,7 +405,7 @@ endif
@set -e ; cd zlib && $(MAKE) clean
@set -e ; cd pcre && $(MAKE) clean
-.PHONY: all sae zlib pcre clean
+.PHONY: all zlib pcre clean
docs:
@@ -640,10 +639,6 @@ $(BINDIR)/$(CS_EXECUTABLE): $(CS_SRC)
$(OBJDIR)/%.elib.o: beam/%.c
$(CC) $(ELIB_FLAGS) $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@
-# Disable vfork() for sae (then we don't need the child_setup program)
-$(OBJDIR)/sys_sae.o: sys/$(ERLANG_OSTYPE)/sys.c
- $(CC) -DDISABLE_VFORK=1 $(CFLAGS) $(INCLUDES) -c $< -o $@
-
$(OBJDIR)/%.kp.o: sys/common/%.c
$(CC) -DERTS_KERNEL_POLL_VERSION $(subst -O2, $(GEN_OPT_FLGS), $(CFLAGS)) $(INCLUDES) -c $< -o $@
@@ -689,8 +684,6 @@ endif
INIT_OBJS = $(OBJDIR)/erl_main.o $(PRELOAD)
-INIT_OBJS_SAE = $(OBJDIR)/erl9_start.o
-
EMU_OBJS = \
$(OBJDIR)/beam_emu.o $(OBJDIR)/beam_opcodes.o \
$(OBJDIR)/beam_load.o $(OBJDIR)/beam_bif_load.o \
@@ -735,7 +728,8 @@ RUN_OBJS = \
$(OBJDIR)/erl_drv_thread.o $(OBJDIR)/erl_bif_chksum.o \
$(OBJDIR)/erl_bif_re.o $(OBJDIR)/erl_unicode.o \
$(OBJDIR)/packet_parser.o $(OBJDIR)/safe_hash.o \
- $(OBJDIR)/erl_zlib.o $(OBJDIR)/erl_nif.o
+ $(OBJDIR)/erl_zlib.o $(OBJDIR)/erl_nif.o \
+ $(OBJDIR)/erl_bif_binary.o
ifeq ($(TARGET),win32)
DRV_OBJS = \
@@ -825,7 +819,6 @@ endif
BASE_OBJS = $(RUN_OBJS) $(EMU_OBJS) $(OS_OBJS) $(EXTRA_BASE_OBJS)
OBJS = $(BASE_OBJS) $(DRV_OBJS)
-OBJS_SAE = $(subst sys.o,sys_sae.o,$(OBJS))
ELIB_C_FILES = beam/elib_malloc.c \
beam/elib_memmove.c \
@@ -932,10 +925,6 @@ $(BINDIR)/$(EMULATOR_EXECUTABLE_ELIB): $(INIT_OBJS) $(OBJS_ELIB) $(DEPLIBS)
$(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE_ELIB) \
$(LDFLAGS) $(DEXPORT) $(INIT_OBJS) $(OBJS_ELIB) $(LIBS)
-$(BINDIR)/$(EMULATOR_EXECUTABLE_SAE): $(INIT_OBJS_SAE) $(OBJS_SAE) $(DEPLIBS)
- $(PURIFY) $(LD) -o $(BINDIR)/$(EMULATOR_EXECUTABLE_SAE) \
- $(LDFLAGS) $(DEXPORT) $(INIT_OBJS_SAE) $(OBJS_SAE) $(LIBS)
-
endif
#
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 9ce21089ba..1138c0c871 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -65,6 +65,7 @@ atom EXIT='EXIT'
atom aborted
atom abs_path
atom absoluteURI
+atom ac
atom active
atom all
atom all_but_first
@@ -100,8 +101,15 @@ atom band
atom big
atom bif_return_trap
atom binary
+atom binary_bin_to_list_trap
+atom binary_copy_trap
+atom binary_longest_prefix_trap
+atom binary_longest_suffix_trap
+atom binary_match_trap
+atom binary_matches_trap
atom block
atom blocked
+atom bm
atom bnot
atom bor
atom bxor
@@ -454,6 +462,7 @@ atom scheduler
atom scheduler_id
atom schedulers_online
atom scheme
+atom scope
atom sensitive
atom sequential_tracer
atom sequential_trace_token
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 5b2f032afc..d42e74ccc9 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1539,6 +1539,10 @@ void process_main(void)
/*
* Skeleton for receive statement:
*
+ * recv_mark L1 Optional
+ * call make_ref/monitor Optional
+ * ...
+ * recv_set L1 Optional
* L1: <-------------------+
* <-----------+ |
* | |
@@ -1557,6 +1561,34 @@ void process_main(void)
*
*/
+ OpCase(recv_mark_f): {
+ /*
+ * Save the current position in message buffer and the
+ * the label for the loop_rec/2 instruction for the
+ * the receive statement.
+ */
+ c_p->msg.mark = (BeamInstr *) Arg(0);
+ c_p->msg.saved_last = c_p->msg.last;
+ Next(1);
+ }
+
+ OpCase(i_recv_set): {
+ /*
+ * If the mark is valid (points to the loop_rec/2
+ * instruction that follows), we know that the saved
+ * position points to the first message that could
+ * possibly be matched out.
+ *
+ * If the mark is invalid, we do nothing, meaning that
+ * we will look through all messages in the message queue.
+ */
+ if (c_p->msg.mark == (BeamInstr *) (I+1)) {
+ c_p->msg.save = c_p->msg.saved_last;
+ }
+ I++;
+ /* Fall through to the loop_rec/2 instruction */
+ }
+
/*
* Pick up the next message and place it in x(0).
* If no message, jump to a wait or wait_timeout instruction.
@@ -1994,6 +2026,81 @@ void process_main(void)
goto post_error_handling;
}
+ OpCase(i_gc_bif2_jIId): /* Note, one less parameter than the i_gc_bif1
+ and i_gc_bif3 */
+ {
+ typedef Eterm (*GcBifFunction)(Process*, Eterm*, Uint);
+ GcBifFunction bf;
+ Eterm result;
+ Uint live = (Uint) Arg(2);
+
+ reg[0] = r(0);
+ reg[live++] = tmp_arg1;
+ reg[live] = tmp_arg2;
+ bf = (GcBifFunction) Arg(1);
+ c_p->fcalls = FCALLS;
+ SWAPOUT;
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
+ result = (*bf)(c_p, reg, live);
+ ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ SWAPIN;
+ r(0) = reg[0];
+ ERTS_HOLE_CHECK(c_p);
+ FCALLS = c_p->fcalls;
+ if (is_value(result)) {
+ StoreBifResult(3, result);
+ }
+ if (Arg(0) != 0) {
+ SET_I((BeamInstr *) Arg(0));
+ Goto(*I);
+ }
+ reg[0] = tmp_arg1;
+ reg[1] = tmp_arg2;
+ I = handle_error(c_p, I, reg, translate_gc_bif((void *) bf));
+ goto post_error_handling;
+ }
+
+ OpCase(i_gc_bif3_jIsId):
+ {
+ typedef Eterm (*GcBifFunction)(Process*, Eterm*, Uint);
+ GcBifFunction bf;
+ Eterm arg;
+ Eterm result;
+ Uint live = (Uint) Arg(3);
+
+ GetArg1(2, arg);
+ reg[0] = r(0);
+ reg[live++] = arg;
+ reg[live++] = tmp_arg1;
+ reg[live] = tmp_arg2;
+ bf = (GcBifFunction) Arg(1);
+ c_p->fcalls = FCALLS;
+ SWAPOUT;
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ ERTS_SMP_UNREQ_PROC_MAIN_LOCK(c_p);
+ result = (*bf)(c_p, reg, live);
+ ERTS_SMP_REQ_PROC_MAIN_LOCK(c_p);
+ PROCESS_MAIN_CHK_LOCKS(c_p);
+ SWAPIN;
+ r(0) = reg[0];
+ ERTS_HOLE_CHECK(c_p);
+ FCALLS = c_p->fcalls;
+ if (is_value(result)) {
+ StoreBifResult(4, result);
+ }
+ if (Arg(0) != 0) {
+ SET_I((BeamInstr *) Arg(0));
+ Goto(*I);
+ }
+ reg[0] = arg;
+ reg[1] = tmp_arg1;
+ reg[2] = tmp_arg2;
+ I = handle_error(c_p, I, reg, translate_gc_bif((void *) bf));
+ goto post_error_handling;
+ }
+
/*
* Guards bifs and, or, xor in guards.
*/
@@ -3110,12 +3217,6 @@ apply_bif_or_nif_epilogue:
StoreBifResult(1, result);
}
- OpCase(i_put_tuple_only_Ad): {
- tmp_arg1 = make_tuple(HTOP);
- *HTOP++ = Arg(0);
- StoreBifResult(1, tmp_arg1);
- }
-
OpCase(case_end_s):
GetArg1(0, tmp_arg1);
c_p->fvalue = tmp_arg1;
@@ -3426,42 +3527,6 @@ apply_bif_or_nif_epilogue:
}
}
- OpCase(i_bs_bits_to_bytes_rjd): {
- tmp_arg1 = r(0);
- goto do_bits_to_bytes;
- }
-
- OpCase(i_bs_bits_to_bytes_yjd): {
- tmp_arg1 = yb(Arg(0));
- I++;
- goto do_bits_to_bytes;
-
- OpCase(i_bs_bits_to_bytes_xjd): {
- tmp_arg1 = xb(Arg(0));
- I++;
- }
-
- do_bits_to_bytes:
- {
- if (is_valid_bit_size(tmp_arg1)) {
- tmp_arg1 = make_small(unsigned_val(tmp_arg1) >> 3);
- } else {
- Uint bytes;
- if (!term_to_Uint(tmp_arg1, &bytes)) {
- goto badarg;
- }
- tmp_arg1 = bytes;
- if ((tmp_arg1 & 0x07) != 0) {
- goto badarg;
- }
- SWAPOUT;
- tmp_arg1 = erts_make_integer(tmp_arg1 >> 3, c_p);
- HTOP = HEAP_TOP(c_p);
- }
- StoreBifResult(1, tmp_arg1);
- }
- }
-
OpCase(i_bs_add_jId): {
Uint Unit = Arg(1);
if (is_both_small(tmp_arg1, tmp_arg2)) {
@@ -3499,7 +3564,7 @@ apply_bif_or_nif_epilogue:
/*
* Now we know that one of the arguments is
- * not at small. We must convert both arguments
+ * not a small. We must convert both arguments
* to Uints and check for errors at the same time.
*
* Error checking is tricky.
@@ -4954,6 +5019,10 @@ translate_gc_bif(void* gcf)
return round_1;
} else if (gcf == erts_gc_trunc_1) {
return round_1;
+ } else if (gcf == erts_gc_binary_part_2) {
+ return binary_part_2;
+ } else if (gcf == erts_gc_binary_part_3) {
+ return binary_part_3;
} else {
erl_exit(1, "bad gc bif");
}
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 5e4375fc96..30f276b95a 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -486,9 +486,6 @@ static GenOp* const_select_val(LoaderState* stp, GenOpArg S, GenOpArg Fail,
GenOpArg Size, GenOpArg* Rest);
static GenOp* gen_func_info(LoaderState* stp, GenOpArg mod, GenOpArg Func,
GenOpArg arity, GenOpArg label);
-static GenOp*
-gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
- GenOpArg Src, GenOpArg Dst);
static int freeze_code(LoaderState* stp);
@@ -3358,9 +3355,15 @@ gen_make_fun2(LoaderState* stp, GenOpArg idx)
op->next = NULL;
return op;
}
-
+/*
+ * Rewrite gc_bifs with one parameter (the common case). Utilized
+ * in ops.tab to rewrite instructions calling bif's in guards
+ * to use a garbage collecting implementation. The instructions
+ * are sometimes once again rewritten to handle literals (putting the
+ * parameter in the mostly unused r[0] before the instruction is executed).
+ */
static GenOp*
-gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
+gen_guard_bif1(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
GenOpArg Src, GenOpArg Dst)
{
GenOp* op;
@@ -3372,6 +3375,8 @@ gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
op->a[0] = Fail;
op->a[1].type = TAG_u;
bf = stp->import[Bif.val].bf;
+ /* The translations here need to have a reverse counterpart in
+ beam_emu.c:translate_gc_bif for error handling to work properly. */
if (bf == length_1) {
op->a[1].val = (BeamInstr) (void *) erts_gc_length_1;
} else if (bf == size_1) {
@@ -3398,6 +3403,77 @@ gen_guard_bif(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
return op;
}
+/*
+ * This is used by the ops.tab rule that rewrites gc_bifs with two parameters
+ * The instruction returned is then again rewritten to an i_load instruction
+ * folowed by i_gc_bif2_jIId, to handle literals properly.
+ * As opposed to the i_gc_bif1_jIsId, the instruction i_gc_bif2_jIId is
+ * always rewritten, regardless of if there actually are any literals.
+ */
+static GenOp*
+gen_guard_bif2(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
+ GenOpArg S1, GenOpArg S2, GenOpArg Dst)
+{
+ GenOp* op;
+ BifFunction bf;
+
+ NEW_GENOP(stp, op);
+ op->op = genop_ii_gc_bif2_6;
+ op->arity = 6;
+ op->a[0] = Fail;
+ op->a[1].type = TAG_u;
+ bf = stp->import[Bif.val].bf;
+ /* The translations here need to have a reverse counterpart in
+ beam_emu.c:translate_gc_bif for error handling to work properly. */
+ if (bf == binary_part_2) {
+ op->a[1].val = (BeamInstr) (void *) erts_gc_binary_part_2;
+ } else {
+ abort();
+ }
+ op->a[2] = S1;
+ op->a[3] = S2;
+ op->a[4] = Live;
+ op->a[5] = Dst;
+ op->next = NULL;
+ return op;
+}
+
+/*
+ * This is used by the ops.tab rule that rewrites gc_bifs with three parameters
+ * The instruction returned is then again rewritten to a move instruction that
+ * uses r[0] for temp storage, followed by an i_load instruction,
+ * folowed by i_gc_bif3_jIsId, to handle literals properly. Rewriting
+ * always occur, as with the gc_bif2 counterpart.
+ */
+static GenOp*
+gen_guard_bif3(LoaderState* stp, GenOpArg Fail, GenOpArg Live, GenOpArg Bif,
+ GenOpArg S1, GenOpArg S2, GenOpArg S3, GenOpArg Dst)
+{
+ GenOp* op;
+ BifFunction bf;
+
+ NEW_GENOP(stp, op);
+ op->op = genop_ii_gc_bif3_7;
+ op->arity = 7;
+ op->a[0] = Fail;
+ op->a[1].type = TAG_u;
+ bf = stp->import[Bif.val].bf;
+ /* The translations here need to have a reverse counterpart in
+ beam_emu.c:translate_gc_bif for error handling to work properly. */
+ if (bf == binary_part_3) {
+ op->a[1].val = (BeamInstr) (void *) erts_gc_binary_part_3;
+ } else {
+ abort();
+ }
+ op->a[2] = S1;
+ op->a[3] = S2;
+ op->a[4] = S3;
+ op->a[5] = Live;
+ op->a[6] = Dst;
+ op->next = NULL;
+ return op;
+}
+
/*
* Freeze the code in memory, move the string table into place,
@@ -3464,7 +3540,7 @@ freeze_code(LoaderState* stp)
literal_end = (Uint *) (code+stp->ci);
/*
* Place the literal heap directly after the code and fix up all
- * put_literal instructions that refer to it.
+ * instructions that refer to it.
*/
{
Uint* ptr;
diff --git a/erts/emulator/beam/bif.c b/erts/emulator/beam/bif.c
index 85bf584337..10cc2e9003 100644
--- a/erts/emulator/beam/bif.c
+++ b/erts/emulator/beam/bif.c
@@ -4143,54 +4143,6 @@ void erts_init_bif(void)
await_proc_exit_trap = erts_export_put(am_erlang,am_await_proc_exit,3);
}
-BIF_RETTYPE blocking_read_file_1(BIF_ALIST_1)
-{
- Eterm bin;
- Eterm* hp;
- byte *buff;
- int i, buff_size;
- FILE *file;
- struct stat file_info;
- char *filename = NULL;
- size_t size;
-
- i = list_length(BIF_ARG_1);
- if (i < 0) {
- BIF_ERROR(BIF_P, BADARG);
- }
- filename = erts_alloc(ERTS_ALC_T_TMP, i + 1);
- if (intlist_to_buf(BIF_ARG_1, filename, i) != i)
- erl_exit(1, "%s:%d: Internal error\n", __FILE__, __LINE__);
- filename[i] = '\0';
-
- hp = HAlloc(BIF_P, 3);
-
- file = fopen(filename, "r");
- if(file == NULL){
- erts_free(ERTS_ALC_T_TMP, (void *) filename);
- BIF_RET(TUPLE2(hp, am_error, am_nofile));
- }
-
- stat(filename, &file_info);
- erts_free(ERTS_ALC_T_TMP, (void *) filename);
-
- buff_size = file_info.st_size;
- buff = (byte *) erts_alloc_fnf(ERTS_ALC_T_TMP, buff_size);
- if (!buff) {
- fclose(file);
- BIF_RET(TUPLE2(hp, am_error, am_allocator));
- }
- size = fread(buff, 1, buff_size, file);
- fclose(file);
- 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));
-}
#ifdef HARDDEBUG
/*
You'll need this line in bif.tab to be able to use this debug bif
diff --git a/erts/emulator/beam/bif.tab b/erts/emulator/beam/bif.tab
index b6fa06354a..38e2dd77d3 100644
--- a/erts/emulator/beam/bif.tab
+++ b/erts/emulator/beam/bif.tab
@@ -686,8 +686,6 @@ bif 'erl.system.code':make_stub_module/3 ebif_code_make_stub_module_3
bif code:is_module_native/1
bif 'erl.system.code':is_native/1 ebif_code_is_native_1 code_is_module_native_1
-bif erlang:blocking_read_file/1
-
#
# New Bifs in R9C.
#
@@ -760,6 +758,40 @@ bif erlang:finish_after_on_load/2
bif erlang:binary_to_term/2
#
+# The binary match bifs (New in R14A - EEP9)
+#
+
+#
+# The searching/splitting/substituting thingies
+#
+ubif erlang:binary_part/2
+ubif erlang:binary_part/3
+
+bif binary:compile_pattern/1
+bif binary:match/2
+bif binary:match/3
+bif binary:matches/2
+bif binary:matches/3
+bif binary:longest_common_prefix/1
+bif binary:longest_common_suffix/1
+bif binary:first/1
+bif binary:last/1
+bif binary:at/2
+bif binary:part/2 binary_binary_part_2
+bif binary:part/3 binary_binary_part_3
+bif binary:bin_to_list/1
+bif binary:bin_to_list/2
+bif binary:bin_to_list/3
+bif binary:list_to_bin/1
+bif binary:copy/1
+bif binary:copy/2
+bif binary:referenced_byte_size/1
+bif binary:encode_unsigned/1
+bif binary:encode_unsigned/2
+bif binary:decode_unsigned/1
+bif binary:decode_unsigned/2
+
+#
# Obsolete
#
diff --git a/erts/emulator/beam/binary.c b/erts/emulator/beam/binary.c
index 59c20398d5..c68392fad4 100644
--- a/erts/emulator/beam/binary.c
+++ b/erts/emulator/beam/binary.c
@@ -180,7 +180,7 @@ erts_realloc_binary(Eterm bin, size_t size)
}
byte*
-erts_get_aligned_binary_bytes_extra(Eterm bin, byte** base_ptr, unsigned extra)
+erts_get_aligned_binary_bytes_extra(Eterm bin, byte** base_ptr, ErtsAlcType_t allocator, unsigned extra)
{
byte* bytes;
Eterm* real_bin;
@@ -208,7 +208,7 @@ erts_get_aligned_binary_bytes_extra(Eterm bin, byte** base_ptr, unsigned extra)
bytes = (byte *)(&(((ErlHeapBin *) real_bin)->data)) + offs;
}
if (bit_offs) {
- byte* buf = (byte *) erts_alloc(ERTS_ALC_T_TMP, byte_size + extra);
+ byte* buf = (byte *) erts_alloc(allocator, byte_size + extra);
*base_ptr = buf;
buf += extra;
erts_copy_bits(bytes, bit_offs, 1, buf, 0, 1, byte_size*8);
@@ -346,29 +346,40 @@ BIF_RETTYPE bitstring_to_list_1(BIF_ALIST_1)
/* Turn a possibly deep list of ints (and binaries) into */
/* One large binary object */
-BIF_RETTYPE list_to_binary_1(BIF_ALIST_1)
+/*
+ * This bif also exists in the binary module, under the name
+ * binary:list_to_bin/1, why it's divided into interface and
+ * implementation. Also the backend for iolist_to_binary_1.
+ */
+
+BIF_RETTYPE erts_list_to_binary_bif(Process *p, Eterm arg)
{
Eterm bin;
int i;
int offset;
byte* bytes;
- if (is_nil(BIF_ARG_1)) {
- BIF_RET(new_binary(BIF_P,(byte*)"",0));
+ if (is_nil(arg)) {
+ BIF_RET(new_binary(p,(byte*)"",0));
}
- if (is_not_list(BIF_ARG_1)) {
+ if (is_not_list(arg)) {
goto error;
}
- if ((i = io_list_len(BIF_ARG_1)) < 0) {
+ if ((i = io_list_len(arg)) < 0) {
goto error;
}
- bin = new_binary(BIF_P, (byte *)NULL, i);
+ bin = new_binary(p, (byte *)NULL, i);
bytes = binary_bytes(bin);
- offset = io_list_to_buf(BIF_ARG_1, (char*) bytes, i);
+ offset = io_list_to_buf(arg, (char*) bytes, i);
ASSERT(offset == 0);
BIF_RET(bin);
- error:
- BIF_ERROR(BIF_P, BADARG);
+ error:
+ BIF_ERROR(p, BADARG);
+}
+
+BIF_RETTYPE list_to_binary_1(BIF_ALIST_1)
+{
+ return erts_list_to_binary_bif(BIF_P, BIF_ARG_1);
}
/* Turn a possibly deep list of ints (and binaries) into */
@@ -376,31 +387,10 @@ BIF_RETTYPE list_to_binary_1(BIF_ALIST_1)
BIF_RETTYPE iolist_to_binary_1(BIF_ALIST_1)
{
- Eterm bin;
- int i;
- int offset;
- byte* bytes;
-
if (is_binary(BIF_ARG_1)) {
BIF_RET(BIF_ARG_1);
}
- if (is_nil(BIF_ARG_1)) {
- BIF_RET(new_binary(BIF_P,(byte*)"",0));
- }
- if (is_not_list(BIF_ARG_1)) {
- goto error;
- }
- if ((i = io_list_len(BIF_ARG_1)) < 0) {
- goto error;
- }
- bin = new_binary(BIF_P, (byte *)NULL, i);
- bytes = binary_bytes(bin);
- offset = io_list_to_buf(BIF_ARG_1, (char*) bytes, i);
- ASSERT(offset == 0);
- BIF_RET(bin);
-
- error:
- BIF_ERROR(BIF_P, BADARG);
+ return erts_list_to_binary_bif(BIF_P, BIF_ARG_1);
}
BIF_RETTYPE list_to_bitstring_1(BIF_ALIST_1)
@@ -675,3 +665,4 @@ bitstr_list_len(Eterm obj)
DESTROY_ESTACK(s);
return (Sint) -1;
}
+
diff --git a/erts/emulator/beam/break.c b/erts/emulator/beam/break.c
index 5cb1481a3a..857cb177c8 100644
--- a/erts/emulator/beam/break.c
+++ b/erts/emulator/beam/break.c
@@ -258,12 +258,10 @@ print_process_info(int to, void *to_arg, Process *p)
}
{
- long s = 0;
int frags = 0;
ErlHeapFragment *m = p->mbuf;
while (m != NULL) {
frags++;
- s += m->size;
m = m->next;
}
erts_print(to, to_arg, "Number of heap fragments: %d\n", frags);
diff --git a/erts/emulator/beam/copy.c b/erts/emulator/beam/copy.c
index 0a5050b1fe..521a1b1788 100644
--- a/erts/emulator/beam/copy.c
+++ b/erts/emulator/beam/copy.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%
*/
@@ -37,6 +37,8 @@ MA_STACK_DECLARE(dst);
MA_STACK_DECLARE(offset);
#endif
+static void move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap*);
+
void
init_copy(void)
{
@@ -86,7 +88,7 @@ size_object(Eterm obj)
obj = *ptr++;
if (!IS_CONST(obj)) {
ESTACK_PUSH(s, obj);
- }
+ }
obj = *ptr;
break;
case TAG_PRIMARY_BOXED:
@@ -99,7 +101,7 @@ size_object(Eterm obj)
arity = header_arity(hdr);
sum += arity + 1;
if (arity == 0) { /* Empty tuple -- unusual. */
- goto size_common;
+ goto pop_next;
}
while (arity-- > 1) {
obj = *++ptr;
@@ -115,7 +117,6 @@ size_object(Eterm obj)
ErlFunThing* funp = (ErlFunThing *) bptr;
unsigned eterms = 1 /* creator */ + funp->num_free;
unsigned sz = thing_arityval(hdr);
-
sum += 1 /* header */ + sz + eterms;
bptr += 1 /* header */ + sz;
while (eterms-- > 1) {
@@ -151,7 +152,7 @@ size_object(Eterm obj)
} else {
sum += heap_bin_size(binary_size(obj)+extra_bytes);
}
- goto size_common;
+ goto pop_next;
}
break;
case BIN_MATCHSTATE_SUBTAG:
@@ -159,18 +160,12 @@ size_object(Eterm obj)
"size_object: matchstate term not allowed");
default:
sum += thing_arityval(hdr) + 1;
- /* Fall through */
- size_common:
- if (ESTACK_ISEMPTY(s)) {
- DESTROY_ESTACK(s);
- return sum;
- }
- obj = ESTACK_POP(s);
- break;
+ goto pop_next;
}
}
break;
case TAG_PRIMARY_IMMED1:
+ pop_next:
if (ESTACK_ISEMPTY(s)) {
DESTROY_ESTACK(s);
return sum;
@@ -979,3 +974,104 @@ copy_shallow(Eterm* ptr, Uint sz, Eterm** hpp, ErlOffHeap* off_heap)
*hpp = hp;
return make_tuple(ptr + offs);
}
+
+/* Move all terms in heap fragments into heap. The terms must be guaranteed to
+ * be contained within the fragments. The source terms are destructed with
+ * move markers.
+ * Typically used to copy a multi-fragmented message (from NIF).
+ */
+void move_multi_frags(Eterm** hpp, ErlOffHeap* off_heap, ErlHeapFragment* first,
+ Eterm* refs, unsigned nrefs)
+{
+ ErlHeapFragment* bp;
+ Eterm* hp_start = *hpp;
+ Eterm* hp_end;
+ Eterm* hp;
+ unsigned i;
+
+ for (bp=first; bp!=NULL; bp=bp->next) {
+ move_one_frag(hpp, bp->mem, bp->used_size, off_heap);
+ off_heap->overhead += bp->off_heap.overhead;
+ }
+ hp_end = *hpp;
+ for (hp=hp_start; hp<hp_end; ++hp) {
+ Eterm* ptr;
+ Eterm val;
+ Eterm gval = *hp;
+ switch (primary_tag(gval)) {
+ case TAG_PRIMARY_BOXED:
+ ptr = boxed_val(gval);
+ val = *ptr;
+ if (IS_MOVED_BOXED(val)) {
+ ASSERT(is_boxed(val));
+ *hp = val;
+ }
+ break;
+ case TAG_PRIMARY_LIST:
+ ptr = list_val(gval);
+ val = *ptr;
+ if (IS_MOVED_CONS(val)) {
+ *hp = ptr[1];
+ }
+ break;
+ case TAG_PRIMARY_HEADER:
+ if (header_is_thing(gval)) {
+ hp += thing_arityval(gval);
+ }
+ break;
+ }
+ }
+ for (i=0; i<nrefs; ++i) {
+ refs[i] = follow_moved(refs[i]);
+ }
+}
+
+static void
+move_one_frag(Eterm** hpp, Eterm* src, Uint src_sz, ErlOffHeap* off_heap)
+{
+ union {
+ Uint *up;
+ ProcBin *pbp;
+ ErlFunThing *efp;
+ ExternalThing *etp;
+ } ohe;
+ Eterm* ptr = src;
+ Eterm* end = ptr + src_sz;
+ Eterm dummy_ref;
+ Eterm* hp = *hpp;
+
+ 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);
+ ohe.up = hp;
+ MOVE_BOXED(ptr, val, hp, &dummy_ref);
+ switch (val & _HEADER_SUBTAG_MASK) {
+ case REFC_BINARY_SUBTAG:
+ ohe.pbp->next = off_heap->mso;
+ off_heap->mso = ohe.pbp;
+ break;
+ case FUN_SUBTAG:
+ ohe.efp->next = off_heap->funs;
+ off_heap->funs = ohe.efp;
+ break;
+ case EXTERNAL_PID_SUBTAG:
+ case EXTERNAL_PORT_SUBTAG:
+ case EXTERNAL_REF_SUBTAG:
+ ohe.etp->next = off_heap->externals;
+ off_heap->externals = ohe.etp;
+ break;
+ }
+ }
+ else { /* must be a cons cell */
+ ASSERT(ptr+1 < end);
+ MOVE_CONS(ptr, val, hp, &dummy_ref);
+ ptr += 2;
+ }
+ }
+ *hpp = hp;
+}
+
diff --git a/erts/emulator/beam/erl_alloc.types b/erts/emulator/beam/erl_alloc.types
index 5d2872a4e3..6f88bbe5b8 100644
--- a/erts/emulator/beam/erl_alloc.types
+++ b/erts/emulator/beam/erl_alloc.types
@@ -232,6 +232,7 @@ type RE_SUBJECT SHORT_LIVED SYSTEM re_subject
type RE_HEAP STANDARD SYSTEM re_heap
type RE_STACK SHORT_LIVED SYSTEM re_stack
type UNICODE_BUFFER SHORT_LIVED SYSTEM unicode_buffer
+type BINARY_BUFFER SHORT_LIVED SYSTEM binary_buffer
type PRE_ALLOC_DATA LONG_LIVED SYSTEM pre_alloc_data
type DRV_THR_OPTS DRIVER SYSTEM driver_thread_opts
type DRV_TID DRIVER SYSTEM driver_tid
diff --git a/erts/emulator/beam/erl_bif_binary.c b/erts/emulator/beam/erl_bif_binary.c
new file mode 100644
index 0000000000..82f1e06e8e
--- /dev/null
+++ b/erts/emulator/beam/erl_bif_binary.c
@@ -0,0 +1,2930 @@
+/*
+ * %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%
+ */
+
+/*
+ * NOTE: This file contains the BIF's for the *module* binary in stdlib.
+ * other BIF's concerning binaries are in binary.c.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sys.h"
+#include "erl_vm.h"
+#include "global.h"
+#include "erl_process.h"
+#include "error.h"
+#include "bif.h"
+#include "big.h"
+#include "erl_binary.h"
+#include "erl_bits.h"
+
+
+/*
+ * The native implementation functions for the module binary.
+ * Searching is implemented using either Boyer-Moore or Aho-Corasick
+ * depending on number of searchstrings (BM if one, AC if more than one).
+ * Native implementation is mostly for efficiency, nothing
+ * (except binary:referenced_byte_size) really *needs* to be implemented
+ * in native code.
+ */
+
+/* #define HARDDEBUG */
+
+/* Init and local variables */
+
+static Export binary_match_trap_export;
+static BIF_RETTYPE binary_match_trap(BIF_ALIST_3);
+static Export binary_matches_trap_export;
+static BIF_RETTYPE binary_matches_trap(BIF_ALIST_3);
+static Export binary_longest_prefix_trap_export;
+static BIF_RETTYPE binary_longest_prefix_trap(BIF_ALIST_3);
+static Export binary_longest_suffix_trap_export;
+static BIF_RETTYPE binary_longest_suffix_trap(BIF_ALIST_3);
+static Export binary_bin_to_list_trap_export;
+static BIF_RETTYPE binary_bin_to_list_trap(BIF_ALIST_3);
+static Export binary_copy_trap_export;
+static BIF_RETTYPE binary_copy_trap(BIF_ALIST_2);
+static Uint max_loop_limit;
+
+
+void erts_init_bif_binary(void)
+{
+ sys_memset((void *) &binary_match_trap_export, 0, sizeof(Export));
+ binary_match_trap_export.address = &binary_match_trap_export.code[3];
+ binary_match_trap_export.code[0] = am_erlang;
+ binary_match_trap_export.code[1] = am_binary_match_trap;
+ binary_match_trap_export.code[2] = 3;
+ binary_match_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ binary_match_trap_export.code[4] = (BeamInstr) &binary_match_trap;
+
+ sys_memset((void *) &binary_matches_trap_export, 0, sizeof(Export));
+ binary_matches_trap_export.address = &binary_matches_trap_export.code[3];
+ binary_matches_trap_export.code[0] = am_erlang;
+ binary_matches_trap_export.code[1] = am_binary_matches_trap;
+ binary_matches_trap_export.code[2] = 3;
+ binary_matches_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ binary_matches_trap_export.code[4] = (BeamInstr) &binary_matches_trap;
+
+ sys_memset((void *) &binary_longest_prefix_trap_export, 0, sizeof(Export));
+ binary_longest_prefix_trap_export.address = &binary_longest_prefix_trap_export.code[3];
+ binary_longest_prefix_trap_export.code[0] = am_erlang;
+ binary_longest_prefix_trap_export.code[1] = am_binary_longest_prefix_trap;
+ binary_longest_prefix_trap_export.code[2] = 3;
+ binary_longest_prefix_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ binary_longest_prefix_trap_export.code[4] = (BeamInstr) &binary_longest_prefix_trap;
+
+ sys_memset((void *) &binary_longest_suffix_trap_export, 0, sizeof(Export));
+ binary_longest_suffix_trap_export.address = &binary_longest_suffix_trap_export.code[3];
+ binary_longest_suffix_trap_export.code[0] = am_erlang;
+ binary_longest_suffix_trap_export.code[1] = am_binary_longest_suffix_trap;
+ binary_longest_suffix_trap_export.code[2] = 3;
+ binary_longest_suffix_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ binary_longest_suffix_trap_export.code[4] = (BeamInstr) &binary_longest_suffix_trap;
+
+ sys_memset((void *) &binary_bin_to_list_trap_export, 0, sizeof(Export));
+ binary_bin_to_list_trap_export.address = &binary_bin_to_list_trap_export.code[3];
+ binary_bin_to_list_trap_export.code[0] = am_erlang;
+ binary_bin_to_list_trap_export.code[1] = am_binary_bin_to_list_trap;
+ binary_bin_to_list_trap_export.code[2] = 3;
+ binary_bin_to_list_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ binary_bin_to_list_trap_export.code[4] = (BeamInstr) &binary_bin_to_list_trap;
+ sys_memset((void *) &binary_copy_trap_export, 0, sizeof(Export));
+ binary_copy_trap_export.address = &binary_copy_trap_export.code[3];
+ binary_copy_trap_export.code[0] = am_erlang;
+ binary_copy_trap_export.code[1] = am_binary_copy_trap;
+ binary_copy_trap_export.code[2] = 2;
+ binary_copy_trap_export.code[3] = (BeamInstr) em_apply_bif;
+ binary_copy_trap_export.code[4] = (BeamInstr) &binary_copy_trap;
+
+ max_loop_limit = 0;
+ return;
+}
+
+/*
+ * Setting the loop_limit for searches for debugging
+ */
+Sint erts_binary_set_loop_limit(Sint limit)
+{
+ Sint save = (Sint) max_loop_limit;
+ if (limit <= 0) {
+ max_loop_limit = 0;
+ } else {
+ max_loop_limit = (Uint) limit;
+ }
+
+ return save;
+}
+
+static Uint get_reds(Process *p, int loop_factor)
+{
+ Uint reds = ERTS_BIF_REDS_LEFT(p) * loop_factor;
+ Uint tmp = max_loop_limit;
+ if (tmp != 0 && tmp < reds) {
+ return tmp;
+ }
+ if (!reds) {
+ reds = 1;
+ }
+ return reds;
+}
+
+/*
+ * A micro allocator used when building search structures, just a convenience
+ * for building structures inside a pre-allocated magic binary using
+ * conventional malloc-like interface.
+ */
+
+#define MYALIGN(Size) (SIZEOF_VOID_P * (((Size) / SIZEOF_VOID_P) + \
+ !!(((Size) % SIZEOF_VOID_P))))
+
+#ifdef DEBUG
+#define CHECK_ALLOCATOR(My) ASSERT((My).current <= ((My).mem + (My).size))
+#else
+#define CHECK_ALLOCATOR(My) /* nothing */
+#endif
+
+typedef struct _my_allocator {
+ Uint size;
+ byte *current;
+ byte *mem;
+} MyAllocator;
+
+static void init_my_allocator(MyAllocator *my, Uint siz, byte *array)
+{
+ ASSERT((siz % SIZEOF_VOID_P) == 0);
+ my->size = siz;
+ my->mem = array;
+ my->current = my->mem;
+}
+
+static void *my_alloc(MyAllocator *my, Uint size)
+{
+ void *ptr = my->current;
+ my->current += MYALIGN(size);
+ return ptr;
+}
+
+/*
+ * The search functionality.
+ *
+ * The search is byte oriented, which works nicely for UTF-8 as well as
+ * latin1 data
+ */
+
+#define ALPHABET_SIZE 256
+
+typedef struct _ac_node {
+#ifdef HARDDEBUG
+ Uint32 id; /* To identify h pointer targets when
+ dumping */
+#endif
+ Uint32 d; /* Depth in trie, also represents the
+ length (-1) of the matched string if
+ in final set */
+ Sint32 final; /* Members in final set represent
+ * matches.
+ * The set representation is scattered
+ * among the nodes in this way:
+ * >0 -> this represents a member of
+ * the final set, <0 -> member of
+ * final set somewhere in the failure
+ * chain,
+ * 0 -> not member of the final set */
+ struct _ac_node *h; /* h(Hode) is the failure function */
+ struct _ac_node *g[ALPHABET_SIZE]; /* g(Node,Character) is the
+ transition function */
+} ACNode;
+
+typedef struct _ac_trie {
+#ifdef HARDDEBUG
+ Uint32 idc;
+#endif
+ Uint32 counter; /* Number of added patterns */
+ ACNode *root; /* pointer to the root state */
+} ACTrie;
+
+typedef struct _bm_data {
+ byte *x;
+ Sint len;
+ Sint *goodshift;
+ Sint badshift[ALPHABET_SIZE];
+} BMData;
+
+#ifdef HARDDEBUG
+static void dump_bm_data(BMData *bm);
+static void dump_ac_trie(ACTrie *act);
+static void dump_ac_node(ACNode *node, int indent, int ch);
+#endif
+
+/*
+ * The needed size of binary data for a search structure - given the
+ * accumulated string lengths.
+ */
+#define BM_SIZE(StrLen) /* StrLen: length of searchstring */ \
+((MYALIGN(sizeof(Sint) * (StrLen))) + /* goodshift array */ \
+ MYALIGN(StrLen) + /* searchstring saved */ \
+ (MYALIGN(sizeof(BMData)))) /* Structure */
+
+#define AC_SIZE(StrLens) /* StrLens: sum of all searchstring lengths */ \
+((MYALIGN(sizeof(ACNode)) * \
+((StrLens)+1)) + /* The actual nodes (including rootnode) */ \
+ MYALIGN(sizeof(ACTrie))) /* Structure */
+
+
+#ifndef MAX
+#define MAX(A,B) (((A) > (B)) ? (A) : (B))
+#endif
+
+#ifndef MIN
+#define MIN(A,B) (((A) > (B)) ? (B) : (A))
+#endif
+/*
+ * Callback for the magic binary
+ */
+static void cleanup_my_data_ac(Binary *bp)
+{
+ return;
+}
+static void cleanup_my_data_bm(Binary *bp)
+{
+ return;
+}
+
+/*
+ * Initiate a (allocated) micro allocator and fill in the base
+ * for an Aho-Corasick search trie, given the accumulated length of the search
+ * strings.
+ */
+static ACTrie *create_acdata(MyAllocator *my, Uint len,
+ ACNode ***qbuff /* out */,
+ Binary **the_bin /* out */)
+{
+ Uint datasize = AC_SIZE(len);
+ ACTrie *act;
+ ACNode *acn;
+ Binary *mb = erts_create_magic_binary(datasize,cleanup_my_data_ac);
+ byte *data = ERTS_MAGIC_BIN_DATA(mb);
+
+ init_my_allocator(my, datasize, data);
+ act = my_alloc(my, sizeof(ACTrie)); /* Important that this is the first
+ allocation */
+ act->counter = 0;
+ act->root = acn = my_alloc(my, sizeof(ACNode));
+ acn->d = 0;
+ acn->final = 0;
+ acn->h = NULL;
+ memset(acn->g, 0, sizeof(ACNode *) * ALPHABET_SIZE);
+#ifdef HARDDEBUG
+ act->idc = 0;
+ acn->id = 0;
+#endif
+ *qbuff = erts_alloc(ERTS_ALC_T_TMP, sizeof(ACNode *) * len);
+ *the_bin = mb;
+ return act;
+}
+
+/*
+ * The same initialization of allocator and basic data for Boyer-Moore.
+ */
+static BMData *create_bmdata(MyAllocator *my, byte *x, Uint len,
+ Binary **the_bin /* out */)
+{
+ Uint datasize = BM_SIZE(len);
+ BMData *bmd;
+ Binary *mb = erts_create_magic_binary(datasize,cleanup_my_data_bm);
+ byte *data = ERTS_MAGIC_BIN_DATA(mb);
+ init_my_allocator(my, datasize, data);
+ bmd = my_alloc(my, sizeof(BMData));
+ bmd->x = my_alloc(my,len);
+ memcpy(bmd->x,x,len);
+ bmd->len = len;
+ bmd->goodshift = my_alloc(my,sizeof(Uint) * len);
+ *the_bin = mb;
+ return bmd;
+}
+
+/*
+ * Compilation of search structures
+ */
+
+/*
+ * Aho Corasick - Build a Trie and fill in the failure functions
+ * when all strings are added.
+ * The algorithm is nicely described by Dieter B�hler of University of
+ * T�bingen:
+ * http://www-sr.informatik.uni-tuebingen.de/~buehler/AC/AC.html
+ */
+
+/*
+ * Helper called once for each search pattern
+ */
+static void ac_add_one_pattern(MyAllocator *my, ACTrie *act, byte *x, Uint len)
+{
+ ACNode *acn = act->root;
+ Uint32 n = ++act->counter; /* Always increase counter, even if it's a
+ duplicate as this may identify the pattern
+ in the final set (not in current interface
+ though) */
+ Uint i = 0;
+
+ while(i < len) {
+ if (acn->g[x[i]] != NULL) {
+ /* node exists, continue */
+ acn = acn->g[x[i]];
+ ++i;
+ } else {
+ /* allocate a new node */
+ ACNode *nn = my_alloc(my,sizeof(ACNode));
+#ifdef HARDDEBUG
+ nn->id = ++(act->idc);
+#endif
+ nn->d = i+1;
+ nn->h = act->root;
+ nn->final = 0;
+ memset(nn->g, 0, sizeof(ACNode *) * ALPHABET_SIZE);
+ acn->g[x[i]] = nn;
+ ++i;
+ acn = nn;
+ }
+ }
+ if (acn->final == 0) { /* New pattern, add to final set */
+ acn->final = n;
+ }
+}
+
+/*
+ * Called when all search patterns are added.
+ */
+static void ac_compute_failure_functions(ACTrie *act, ACNode **qbuff)
+{
+ ACNode *root = act->root;
+ ACNode *parent;
+ int i;
+ int qh = 0,qt = 0;
+ ACNode *child, *r;
+
+ /* Set all children of the root to have the root as failure function */
+ for (i = 0; i < ALPHABET_SIZE; ++i) {
+ if (root->g[i] != NULL) {
+ root->g[i]->h = root;
+ /* Add to que for later traversal */
+ qbuff[qt++] = root->g[i];
+ }
+ }
+
+ /* So, now we've handled children of the root state, traverse the
+ rest of the trie BF... */
+ while (qh < qt) {
+ parent = qbuff[qh++];
+ for (i = 0; i < ALPHABET_SIZE; ++ i) {
+ if ((child = parent->g[i]) != NULL) {
+ /* Visit this node to */
+ qbuff[qt++] = child;
+ /* Search for correct failure function, follow the parent's
+ failure function until you find a similar transition
+ funtion to this child's */
+ r = parent->h;
+ while (r != NULL && r->g[i] == NULL) {
+ r = r->h;
+ }
+ if (r == NULL) {
+ /* Replace NULL failures with the root as we go */
+ child->h = (root->g[i] == NULL) ? root : root->g[i];
+ } else {
+ child->h = r->g[i];
+ /*
+ * The "final" set is scattered among the nodes. When
+ * the failure function points to a member of the final
+ * set, we have a match, but we might not see it in the
+ * current node if we dont mark it as a special type of
+ * final, i.e. foolow the failure function and you will
+ * find a real member of final set. This is marked with
+ * a negative string id and only done if this node does
+ * not represent a member in the final set.
+ */
+ if (!(child->final) && (child->h->final)) {
+ child->final = -1;
+ }
+ }
+ }
+ }
+ }
+ /* Finally the failure function of the root should point to itself */
+ root->h = root;
+}
+
+
+/*
+ * The actual searching for needles in the haystack...
+ * Find first match using Aho-Coracick Trie
+ * return pattern number and fill in mpos + mlen if found, otherwise return 0
+ * Return the matching pattern that *starts* first, and ends
+ * last (difference when overlapping), hence the candidate thing.
+ * Basic AC finds the first end before the first start...
+ *
+ */
+typedef struct {
+ ACNode *q;
+ Uint pos;
+ Uint len;
+ ACNode *candidate;
+ Uint candidate_start;
+} ACFindFirstState;
+
+
+static void ac_init_find_first_match(ACFindFirstState *state, ACTrie *act, Sint startpos, Uint len)
+{
+ state->q = act->root;
+ state->pos = startpos;
+ state->len = len;
+ state->candidate = NULL;
+ state->candidate_start = 0;
+}
+#define AC_OK 0
+#define AC_NOT_FOUND -1
+#define AC_RESTART -2
+
+#define AC_LOOP_FACTOR 10
+
+static int ac_find_first_match(ACFindFirstState *state, byte *haystack,
+ Uint *mpos, Uint *mlen, Uint *reductions)
+{
+ ACNode *q = state->q;
+ Uint i = state->pos;
+ ACNode *candidate = state->candidate, *r;
+ Uint len = state->len;
+ Uint candidate_start = state->candidate_start;
+ Uint rstart;
+ register Uint reds = *reductions;
+
+ while (i < len) {
+ if (--reds == 0) {
+ state->q = q;
+ state->pos = i;
+ state->len = len;
+ state->candidate = candidate;
+ state->candidate_start = candidate_start;
+ return AC_RESTART;
+ }
+
+ while (q->g[haystack[i]] == NULL && q->h != q) {
+ q = q->h;
+ }
+ if (q->g[haystack[i]] != NULL) {
+ q = q->g[haystack[i]];
+ }
+#ifdef HARDDEBUG
+ erts_printf("ch = %c, Current: %u\n", (int) haystack[i], (unsigned) q->id);
+#endif
+ ++i;
+ if (candidate != NULL && (i - q->d) > candidate_start) {
+ break;
+ }
+ if (q->final) {
+ r = q;
+ while (r->final < 0)
+ r = r->h;
+ rstart = i - r->d;
+ if (candidate == NULL || rstart < candidate_start ||
+ (rstart == candidate_start && candidate->d < q->d)) {
+ candidate_start = rstart;
+ candidate = r;
+ }
+ }
+ }
+ *reductions = reds;
+ if (!candidate) {
+ return AC_NOT_FOUND;
+ }
+#ifdef HARDDEBUG
+ dump_ac_node(candidate,0,'?');
+#endif
+ *mpos = candidate_start;
+ *mlen = candidate->d;
+ return AC_OK;
+}
+
+typedef struct _findall_data {
+ Uint pos;
+ Uint len;
+#ifdef HARDDEBUG
+ Uint id;
+#endif
+ Eterm epos;
+ Eterm elen;
+} FindallData;
+
+typedef struct {
+ ACNode *q;
+ Uint pos;
+ Uint len;
+ Uint m;
+ Uint allocated;
+ FindallData *out;
+} ACFindAllState;
+
+static void ac_init_find_all(ACFindAllState *state, ACTrie *act, Sint startpos, Uint len)
+{
+ state->q = act->root;
+ state->pos = startpos;
+ state->len = len;
+ state->m = 0;
+ state->allocated = 0;
+ state->out = NULL;
+}
+
+static void ac_restore_find_all(ACFindAllState *state, char *buff)
+{
+ memcpy(state,buff,sizeof(ACFindAllState));
+ state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) * (state->allocated));
+ memcpy(state->out,buff+sizeof(ACFindAllState),sizeof(FindallData)*state->m);
+}
+
+static void ac_serialize_find_all(ACFindAllState *state, char *buff)
+{
+ memcpy(buff,state,sizeof(ACFindAllState));
+ memcpy(buff+sizeof(ACFindAllState),state->out,sizeof(FindallData)*state->m);
+}
+
+static void ac_clean_find_all(ACFindAllState *state)
+{
+ if (state->out != NULL) {
+ erts_free(ERTS_ALC_T_TMP, state->out);
+ }
+#ifdef HARDDEBUG
+ state->out = NULL;
+ state->allocated = 0;
+#endif
+}
+
+#define SIZEOF_AC_SERIALIZED_FIND_ALL_STATE(S) \
+ (sizeof(ACFindAllState)+(sizeof(FindallData)*(S).m))
+
+/*
+ * Differs to the find_first function in that it stores all matches and the values
+ * arte returned only in the state.
+ */
+static int ac_find_all_non_overlapping(ACFindAllState *state, byte *haystack,
+ Uint *reductions)
+{
+ ACNode *q = state->q;
+ Uint i = state->pos;
+ Uint rstart;
+ ACNode *r;
+ Uint len = state->len;
+ Uint m = state->m, save_m;
+ Uint allocated = state->allocated;
+ FindallData *out = state->out;
+ register Uint reds = *reductions;
+
+
+ while (i < len) {
+ if (--reds == 0) {
+ state->q = q;
+ state->pos = i;
+ state->len = len;
+ state->m = m;
+ state->allocated = allocated;
+ state->out = out;
+ return AC_RESTART;
+ }
+ while (q->g[haystack[i]] == NULL && q->h != q) {
+ q = q->h;
+ }
+ if (q->g[haystack[i]] != NULL) {
+ q = q->g[haystack[i]];
+ }
+ ++i;
+ if (q->final) {
+ r = q;
+ while (r->final) {
+ while (r->final < 0)
+ r = r->h;
+#ifdef HARDDEBUG
+ erts_printf("Trying to add %u\n",(unsigned) r->final);
+#endif
+ rstart = i - r->d;
+ save_m = m;
+ while (m > 0 && (out[m-1].pos > rstart ||
+ (out[m-1].pos == rstart &&
+ out[m-1].len < r->d))) {
+#ifdef HARDDEBUG
+ erts_printf("Popping %u\n",(unsigned) out[m-1].id);
+#endif
+ --m;
+ }
+#ifdef HARDDEBUG
+ if (m > 0) {
+ erts_printf("Pos %u\n",out[m-1].pos);
+ erts_printf("Len %u\n",out[m-1].len);
+ }
+ erts_printf("Rstart %u\n",rstart);
+#endif
+ if (m == 0 || out[m-1].pos + out[m-1].len <= rstart) {
+ if (m >= allocated) {
+ if (!allocated) {
+ allocated = 10;
+ out = erts_alloc(ERTS_ALC_T_TMP,
+ sizeof(FindallData) * allocated);
+ } else {
+ allocated *= 2;
+ out = erts_realloc(ERTS_ALC_T_TMP, out,
+ sizeof(FindallData) *
+ allocated);
+ }
+ }
+ out[m].pos = rstart;
+ out[m].len = r->d;
+#ifdef HARDDEBUG
+ out[m].id = r->final;
+#endif
+ ++m;
+#ifdef HARDDEBUG
+ erts_printf("Pushing %u\n",(unsigned) out[m-1].id);
+#endif
+ } else {
+#ifdef HARDDEBUG
+ erts_printf("Backtracking %d steps\n",save_m - m);
+#endif
+ m = save_m;
+ }
+ r = r->h;
+ }
+ }
+ }
+ *reductions = reds;
+ state->m = m;
+ state->out = out;
+ return (m == 0) ? AC_NOT_FOUND : AC_OK;
+}
+
+/*
+ * Boyer Moore - most obviously implemented more or less exactly as
+ * Christian Charras and Thierry Lecroq describe it in "Handbook of
+ * Exact String-Matching Algorithms"
+ * http://www-igm.univ-mlv.fr/~lecroq/string/
+ */
+
+/*
+ * Call this to compute badshifts array
+ */
+static void compute_badshifts(BMData *bmd)
+{
+ Sint i;
+ Sint m = bmd->len;
+
+ for (i = 0; i < ALPHABET_SIZE; ++i) {
+ bmd->badshift[i] = m;
+ }
+ for (i = 0; i < m - 1; ++i) {
+ bmd->badshift[bmd->x[i]] = m - i - 1;
+ }
+}
+
+/* Helper for "compute_goodshifts" */
+static void compute_suffixes(byte *x, Sint m, Sint *suffixes)
+{
+ int f,g,i;
+
+ suffixes[m - 1] = m;
+
+ f = 0; /* To avoid use before set warning */
+
+ g = m - 1;
+
+ for (i = m - 2; i >= 0; --i) {
+ if (i > g && suffixes[i + m - 1 - f] < i - g) {
+ suffixes[i] = suffixes[i + m - 1 - f];
+ } else {
+ if (i < g) {
+ g = i;
+ }
+ f = i;
+ while ( g >= 0 && x[g] == x[g + m - 1 - f] ) {
+ --g;
+ }
+ suffixes[i] = f - g;
+ }
+ }
+}
+
+/*
+ * Call this to compute goodshift array
+ */
+static void compute_goodshifts(BMData *bmd)
+{
+ Sint m = bmd->len;
+ byte *x = bmd->x;
+ Sint i, j;
+ Sint *suffixes = erts_alloc(ERTS_ALC_T_TMP, m * sizeof(Sint));
+
+ compute_suffixes(x, m, suffixes);
+
+ for (i = 0; i < m; ++i) {
+ bmd->goodshift[i] = m;
+ }
+
+ j = 0;
+
+ for (i = m - 1; i >= -1; --i) {
+ if (i == -1 || suffixes[i] == i + 1) {
+ while (j < m - 1 - i) {
+ if (bmd->goodshift[j] == m) {
+ bmd->goodshift[j] = m - 1 - i;
+ }
+ ++j;
+ }
+ }
+ }
+ for (i = 0; i <= m - 2; ++i) {
+ bmd->goodshift[m - 1 - suffixes[i]] = m - 1 - i;
+ }
+ erts_free(ERTS_ALC_T_TMP, suffixes);
+}
+
+typedef struct {
+ Sint pos;
+ Sint len;
+} BMFindFirstState;
+
+#define BM_OK 0 /* used only for find_all */
+#define BM_NOT_FOUND -1
+#define BM_RESTART -2
+#define BM_LOOP_FACTOR 10 /* Should we have a higher value? */
+
+static void bm_init_find_first_match(BMFindFirstState *state, Sint startpos,
+ Uint len)
+{
+ state->pos = startpos;
+ state->len = (Sint) len;
+}
+
+
+static Sint bm_find_first_match(BMFindFirstState *state, BMData *bmd,
+ byte *haystack, Uint *reductions)
+{
+ Sint blen = bmd->len;
+ Sint len = state->len;
+ Sint *gs = bmd->goodshift;
+ Sint *bs = bmd->badshift;
+ byte *needle = bmd->x;
+ Sint i;
+ Sint j = state->pos;
+ register Uint reds = *reductions;
+
+ while (j <= len - blen) {
+ if (--reds == 0) {
+ state->pos = j;
+ return BM_RESTART;
+ }
+ for (i = blen - 1; i >= 0 && needle[i] == haystack[i + j]; --i)
+ ;
+ if (i < 0) { /* found */
+ *reductions = reds;
+ return j;
+ }
+ j += MAX(gs[i],bs[haystack[i+j]] - blen + 1 + i);
+ }
+ *reductions = reds;
+ return BM_NOT_FOUND;
+}
+
+typedef struct {
+ Sint pos;
+ Sint len;
+ Uint m;
+ Uint allocated;
+ FindallData *out;
+} BMFindAllState;
+
+static void bm_init_find_all(BMFindAllState *state, Sint startpos, Uint len)
+{
+ state->pos = startpos;
+ state->len = (Sint) len;
+ state->m = 0;
+ state->allocated = 0;
+ state->out = NULL;
+}
+
+static void bm_restore_find_all(BMFindAllState *state, char *buff)
+{
+ memcpy(state,buff,sizeof(BMFindAllState));
+ state->out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) *
+ (state->allocated));
+ memcpy(state->out,buff+sizeof(BMFindAllState),
+ sizeof(FindallData)*state->m);
+}
+
+static void bm_serialize_find_all(BMFindAllState *state, char *buff)
+{
+ memcpy(buff,state,sizeof(BMFindAllState));
+ memcpy(buff+sizeof(BMFindAllState),state->out,
+ sizeof(FindallData)*state->m);
+}
+
+static void bm_clean_find_all(BMFindAllState *state)
+{
+ if (state->out != NULL) {
+ erts_free(ERTS_ALC_T_TMP, state->out);
+ }
+#ifdef HARDDEBUG
+ state->out = NULL;
+ state->allocated = 0;
+#endif
+}
+
+#define SIZEOF_BM_SERIALIZED_FIND_ALL_STATE(S) \
+ (sizeof(BMFindAllState)+(sizeof(FindallData)*(S).m))
+
+/*
+ * Differs to the find_first function in that it stores all matches and the
+ * values are returned only in the state.
+ */
+static Sint bm_find_all_non_overlapping(BMFindAllState *state,
+ BMData *bmd, byte *haystack,
+ Uint *reductions)
+{
+ Sint blen = bmd->len;
+ Sint len = state->len;
+ Sint *gs = bmd->goodshift;
+ Sint *bs = bmd->badshift;
+ byte *needle = bmd->x;
+ Sint i;
+ Sint j = state->pos;
+ Uint m = state->m;
+ Uint allocated = state->allocated;
+ FindallData *out = state->out;
+ register Uint reds = *reductions;
+
+ while (j <= len - blen) {
+ if (--reds == 0) {
+ state->pos = j;
+ state->m = m;
+ state->allocated = allocated;
+ state->out = out;
+ return BM_RESTART;
+ }
+ for (i = blen - 1; i >= 0 && needle[i] == haystack[i + j]; --i)
+ ;
+ if (i < 0) { /* found */
+ if (m >= allocated) {
+ if (!allocated) {
+ allocated = 10;
+ out = erts_alloc(ERTS_ALC_T_TMP, sizeof(FindallData) * allocated);
+ } else {
+ allocated *= 2;
+ out = erts_realloc(ERTS_ALC_T_TMP, out,
+ sizeof(FindallData) * allocated);
+ }
+ }
+ out[m].pos = j;
+ out[m].len = blen;
+ ++m;
+ j += blen;
+ } else {
+ j += MAX(gs[i],bs[haystack[i+j]] - blen + 1 + i);
+ }
+ }
+ state->m = m;
+ state->out = out;
+ *reductions = reds;
+ return (m == 0) ? BM_NOT_FOUND : BM_OK;
+}
+
+/*
+ * Interface functions (i.e. "bif's")
+ */
+
+/*
+ * Search functionality interfaces
+ */
+
+static int do_binary_match_compile(Eterm argument, Eterm *tag, Binary **binp)
+{
+ Eterm t, b, comp_term = NIL;
+ Uint characters;
+ Uint words;
+
+ characters = 0;
+ words = 0;
+
+ if (is_list(argument)) {
+ t = argument;
+ while (is_list(t)) {
+ b = CAR(list_val(t));
+ t = CDR(list_val(t));
+ if (!is_binary(b)) {
+ goto badarg;
+ }
+ if (binary_bitsize(b) != 0) {
+ goto badarg;
+ }
+ ++words;
+ characters += binary_size(b);
+ }
+ if (is_not_nil(t)) {
+ goto badarg;
+ }
+ if (words > 1) {
+ comp_term = argument;
+ } else {
+ comp_term = CAR(list_val(argument));
+ }
+ } else if (is_binary(argument)) {
+ if (binary_bitsize(argument) != 0) {
+ goto badarg;
+ }
+ words = 1;
+ comp_term = argument;
+ characters = binary_size(argument);
+ }
+
+ if (characters == 0) {
+ goto badarg;
+ }
+ ASSERT(words > 0);
+
+ if (words == 1) {
+ byte *bytes;
+ Uint bitoffs, bitsize;
+ byte *temp_alloc = NULL;
+ MyAllocator my;
+ BMData *bmd;
+ Binary *bin;
+
+ ERTS_GET_BINARY_BYTES(comp_term, bytes, bitoffs, bitsize);
+ if (bitoffs != 0) {
+ bytes = erts_get_aligned_binary_bytes(comp_term, &temp_alloc);
+ }
+ bmd = create_bmdata(&my, bytes, characters, &bin);
+ compute_badshifts(bmd);
+ compute_goodshifts(bmd);
+ erts_free_aligned_binary_bytes(temp_alloc);
+ CHECK_ALLOCATOR(my);
+ *tag = am_bm;
+ *binp = bin;
+ return 0;
+ } else {
+ ACTrie *act;
+ MyAllocator my;
+ ACNode **qbuff;
+ Binary *bin;
+
+ act = create_acdata(&my, characters, &qbuff, &bin);
+ t = comp_term;
+ while (is_list(t)) {
+ byte *bytes;
+ Uint bitoffs, bitsize;
+ byte *temp_alloc = NULL;
+ b = CAR(list_val(t));
+ t = CDR(list_val(t));
+ ERTS_GET_BINARY_BYTES(b, bytes, bitoffs, bitsize);
+ if (bitoffs != 0) {
+ bytes = erts_get_aligned_binary_bytes(b, &temp_alloc);
+ }
+ ac_add_one_pattern(&my,act,bytes,binary_size(b));
+ erts_free_aligned_binary_bytes(temp_alloc);
+ }
+ ac_compute_failure_functions(act,qbuff);
+ CHECK_ALLOCATOR(my);
+ erts_free(ERTS_ALC_T_TMP,qbuff);
+ *tag = am_ac;
+ *binp = bin;
+ return 0;
+ }
+ badarg:
+ return -1;
+}
+
+BIF_RETTYPE binary_compile_pattern_1(BIF_ALIST_1)
+{
+ Binary *bin;
+ Eterm tag, ret;
+ Eterm *hp;
+
+ if (do_binary_match_compile(BIF_ARG_1,&tag,&bin)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ hp = HAlloc(BIF_P, PROC_BIN_SIZE+3);
+ ret = erts_mk_magic_binary_term(&hp, &MSO(BIF_P), bin);
+ ret = TUPLE2(hp, tag, ret);
+ BIF_RET(ret);
+}
+
+#define DO_BIN_MATCH_OK 0
+#define DO_BIN_MATCH_BADARG -1
+#define DO_BIN_MATCH_RESTART -2
+
+static int do_binary_match(Process *p, Eterm subject, Uint hsstart, Uint hsend,
+ Eterm type, Binary *bin, Eterm state_term,
+ Eterm *res_term)
+{
+ byte *bytes;
+ Uint bitoffs, bitsize;
+ byte *temp_alloc = NULL;
+
+ ERTS_GET_BINARY_BYTES(subject, bytes, bitoffs, bitsize);
+ if (bitsize != 0) {
+ goto badarg;
+ }
+ if (bitoffs != 0) {
+ bytes = erts_get_aligned_binary_bytes(subject, &temp_alloc);
+ }
+ if (state_term != NIL) {
+ Eterm *ptr = big_val(state_term);
+ type = ptr[1];
+ }
+
+ if (type == am_bm) {
+ BMData *bm;
+ Sint pos;
+ Eterm ret;
+ Eterm *hp;
+ BMFindFirstState state;
+ Uint reds = get_reds(p, BM_LOOP_FACTOR);
+ Uint save_reds = reds;
+
+ bm = (BMData *) ERTS_MAGIC_BIN_DATA(bin);
+#ifdef HARDDEBUG
+ dump_bm_data(bm);
+#endif
+ if (state_term == NIL) {
+ bm_init_find_first_match(&state, hsstart, hsend);
+ } else {
+ Eterm *ptr = big_val(state_term);
+ memcpy(&state,ptr+2,sizeof(state));
+ }
+#ifdef HARDDEBUG
+ erts_printf("(bm) state->pos = %ld, state->len = %lu\n",state.pos,
+ state.len);
+#endif
+ pos = bm_find_first_match(&state, bm, bytes, &reds);
+ if (pos == BM_NOT_FOUND) {
+ ret = am_nomatch;
+ } else if (pos == BM_RESTART) {
+ int x = (sizeof(BMFindFirstState) / sizeof(Eterm)) +
+ !!(sizeof(BMFindFirstState) % sizeof(Eterm));
+#ifdef HARDDEBUG
+ erts_printf("Trap bm!\n");
+#endif
+ hp = HAlloc(p,x+2);
+ hp[0] = make_pos_bignum_header(x+1);
+ hp[1] = type;
+ memcpy(hp+2,&state,sizeof(state));
+ *res_term = make_big(hp);
+ erts_free_aligned_binary_bytes(temp_alloc);
+ return DO_BIN_MATCH_RESTART;
+ } else {
+ Eterm erlen = erts_make_integer((Uint) bm->len, p);
+ ret = erts_make_integer(pos,p);
+ hp = HAlloc(p,3);
+ ret = TUPLE2(hp, ret, erlen);
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BUMP_REDS(p, (save_reds - reds) / BM_LOOP_FACTOR);
+ *res_term = ret;
+ return DO_BIN_MATCH_OK;
+ } else if (type == am_ac) {
+ ACTrie *act;
+ Uint pos, rlen;
+ int acr;
+ ACFindFirstState state;
+ Eterm ret;
+ Eterm *hp;
+ Uint reds = get_reds(p, AC_LOOP_FACTOR);
+ Uint save_reds = reds;
+
+ act = (ACTrie *) ERTS_MAGIC_BIN_DATA(bin);
+#ifdef HARDDEBUG
+ dump_ac_trie(act);
+#endif
+ if (state_term == NIL) {
+ ac_init_find_first_match(&state, act, hsstart, hsend);
+ } else {
+ Eterm *ptr = big_val(state_term);
+ memcpy(&state,ptr+2,sizeof(state));
+ }
+ acr = ac_find_first_match(&state, bytes, &pos, &rlen, &reds);
+ if (acr == AC_NOT_FOUND) {
+ ret = am_nomatch;
+ } else if (acr == AC_RESTART) {
+ int x = (sizeof(state) / sizeof(Eterm)) +
+ !!(sizeof(BMFindFirstState) % sizeof(Eterm));
+#ifdef HARDDEBUG
+ erts_printf("Trap ac!\n");
+#endif
+ hp = HAlloc(p,x+2);
+ hp[0] = make_pos_bignum_header(x+1);
+ hp[1] = type;
+ memcpy(hp+2,&state,sizeof(state));
+ *res_term = make_big(hp);
+ erts_free_aligned_binary_bytes(temp_alloc);
+ return DO_BIN_MATCH_RESTART;
+ } else {
+ Eterm epos = erts_make_integer(pos+hsstart,p);
+ Eterm erlen = erts_make_integer(rlen,p);
+ hp = HAlloc(p,3);
+ ret = TUPLE2(hp, epos, erlen);
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BUMP_REDS(p, (save_reds - reds) / AC_LOOP_FACTOR);
+ *res_term = ret;
+ return DO_BIN_MATCH_OK;
+ }
+ badarg:
+ return DO_BIN_MATCH_BADARG;
+}
+
+static int do_binary_matches(Process *p, Eterm subject, Uint hsstart,
+ Uint hsend, Eterm type, Binary *bin,
+ Eterm state_term, Eterm *res_term)
+{
+ byte *bytes;
+ Uint bitoffs, bitsize;
+ byte *temp_alloc = NULL;
+
+ ERTS_GET_BINARY_BYTES(subject, bytes, bitoffs, bitsize);
+ if (bitsize != 0) {
+ goto badarg;
+ }
+ if (bitoffs != 0) {
+ bytes = erts_get_aligned_binary_bytes(subject, &temp_alloc);
+ }
+ if (state_term != NIL) {
+ Eterm *ptr = big_val(state_term);
+ type = ptr[1];
+ }
+
+ if (type == am_bm) {
+ BMData *bm;
+ Sint pos;
+ Eterm ret,tpl;
+ Eterm *hp;
+ BMFindAllState state;
+ Uint reds = get_reds(p, BM_LOOP_FACTOR);
+ Uint save_reds = reds;
+
+ bm = (BMData *) ERTS_MAGIC_BIN_DATA(bin);
+#ifdef HARDDEBUG
+ dump_bm_data(bm);
+#endif
+ if (state_term == NIL) {
+ bm_init_find_all(&state, hsstart, hsend);
+ } else {
+ Eterm *ptr = big_val(state_term);
+ bm_restore_find_all(&state,(char *) (ptr+2));
+ }
+
+ pos = bm_find_all_non_overlapping(&state, bm, bytes, &reds);
+ if (pos == BM_NOT_FOUND) {
+ ret = NIL;
+ } else if (pos == BM_RESTART) {
+ int x =
+ (SIZEOF_BM_SERIALIZED_FIND_ALL_STATE(state) / sizeof(Eterm)) +
+ !!(SIZEOF_BM_SERIALIZED_FIND_ALL_STATE(state) % sizeof(Eterm));
+#ifdef HARDDEBUG
+ erts_printf("Trap bm!\n");
+#endif
+ hp = HAlloc(p,x+2);
+ hp[0] = make_pos_bignum_header(x+1);
+ hp[1] = type;
+ bm_serialize_find_all(&state, (char *) (hp+2));
+ *res_term = make_big(hp);
+ erts_free_aligned_binary_bytes(temp_alloc);
+ bm_clean_find_all(&state);
+ return DO_BIN_MATCH_RESTART;
+ } else {
+ FindallData *fad = state.out;
+ int i;
+ for (i = 0; i < state.m; ++i) {
+ fad[i].epos = erts_make_integer(fad[i].pos,p);
+ fad[i].elen = erts_make_integer(fad[i].len,p);
+ }
+ hp = HAlloc(p,state.m * (3 + 2));
+ ret = NIL;
+ for (i = state.m - 1; i >= 0; --i) {
+ tpl = TUPLE2(hp, fad[i].epos, fad[i].elen);
+ hp +=3;
+ ret = CONS(hp,tpl,ret);
+ hp += 2;
+ }
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ bm_clean_find_all(&state);
+ BUMP_REDS(p, (save_reds - reds) / BM_LOOP_FACTOR);
+ *res_term = ret;
+ return DO_BIN_MATCH_OK;
+ } else if (type == am_ac) {
+ ACTrie *act;
+ int acr;
+ ACFindAllState state;
+ Eterm ret,tpl;
+ Eterm *hp;
+ Uint reds = get_reds(p, AC_LOOP_FACTOR);
+ Uint save_reds = reds;
+
+ act = (ACTrie *) ERTS_MAGIC_BIN_DATA(bin);
+#ifdef HARDDEBUG
+ dump_ac_trie(act);
+#endif
+ if (state_term == NIL) {
+ ac_init_find_all(&state, act, hsstart, hsend);
+ } else {
+ Eterm *ptr = big_val(state_term);
+ ac_restore_find_all(&state,(char *) (ptr+2));
+ }
+ acr = ac_find_all_non_overlapping(&state, bytes, &reds);
+ if (acr == AC_NOT_FOUND) {
+ ret = NIL;
+ } else if (acr == AC_RESTART) {
+ int x =
+ (SIZEOF_AC_SERIALIZED_FIND_ALL_STATE(state) / sizeof(Eterm)) +
+ !!(SIZEOF_AC_SERIALIZED_FIND_ALL_STATE(state) % sizeof(Eterm));
+#ifdef HARDDEBUG
+ erts_printf("Trap ac!\n");
+#endif
+ hp = HAlloc(p,x+2);
+ hp[0] = make_pos_bignum_header(x+1);
+ hp[1] = type;
+ ac_serialize_find_all(&state, (char *) (hp+2));
+ *res_term = make_big(hp);
+ erts_free_aligned_binary_bytes(temp_alloc);
+ ac_clean_find_all(&state);
+ return DO_BIN_MATCH_RESTART;
+ } else {
+ FindallData *fad = state.out;
+ int i;
+ for (i = 0; i < state.m; ++i) {
+ fad[i].epos = erts_make_integer(fad[i].pos,p);
+ fad[i].elen = erts_make_integer(fad[i].len,p);
+ }
+ hp = HAlloc(p,state.m * (3 + 2));
+ ret = NIL;
+ for (i = state.m - 1; i >= 0; --i) {
+ tpl = TUPLE2(hp, fad[i].epos, fad[i].elen);
+ hp +=3;
+ ret = CONS(hp,tpl,ret);
+ hp += 2;
+ }
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ ac_clean_find_all(&state);
+ BUMP_REDS(p, (save_reds - reds) / AC_LOOP_FACTOR);
+ *res_term = ret;
+ return DO_BIN_MATCH_OK;
+ }
+ badarg:
+ return DO_BIN_MATCH_BADARG;
+}
+
+static int parse_match_opts_list(Eterm l, Eterm bin, Uint *posp, Uint *endp)
+{
+ Eterm *tp;
+ Uint pos;
+ Sint len;
+ if (l == ((Eterm) 0) || l == NIL) {
+ /* Invalid term or NIL, we're called from binary_match(es)_2 or
+ have no options*/
+ *posp = 0;
+ *endp = binary_size(bin);
+ return 0;
+ } else if (is_list(l)) {
+ while(is_list(l)) {
+ Eterm t = CAR(list_val(l));
+ Uint orig_size;
+ if (!is_tuple(t)) {
+ goto badarg;
+ }
+ tp = tuple_val(t);
+ if (arityval(*tp) != 2) {
+ goto badarg;
+ }
+ if (tp[1] != am_scope || is_not_tuple(tp[2])) {
+ goto badarg;
+ }
+ tp = tuple_val(tp[2]);
+ if (arityval(*tp) != 2) {
+ goto badarg;
+ }
+ if (!term_to_Uint(tp[1], &pos)) {
+ goto badarg;
+ }
+ if (!term_to_Sint(tp[2], &len)) {
+ goto badarg;
+ }
+ if (len < 0) {
+ Sint lentmp = -len;
+ /* overflow */
+ if (lentmp == len || lentmp < 0 || -lentmp != len) {
+ goto badarg;
+ }
+ len = lentmp;
+ pos -= len;
+ }
+ /* overflow */
+ if ((pos + len) < pos || (len > 0 && (pos + len) == pos)) {
+ goto badarg;
+ }
+ *endp = len + pos;
+ *posp = pos;
+ if ((orig_size = binary_size(bin)) < pos ||
+ orig_size < (*endp)) {
+ goto badarg;
+ }
+ l = CDR(list_val(l));
+ }
+ return 0;
+ } else {
+ badarg:
+ return 1;
+ }
+}
+
+static BIF_RETTYPE binary_match_trap(BIF_ALIST_3)
+{
+ int runres;
+ Eterm result;
+ Binary *bin = ((ProcBin *) binary_val(BIF_ARG_3))->val;
+ runres = do_binary_match(BIF_P,BIF_ARG_1,0,0,NIL,bin,BIF_ARG_2,&result);
+ if (runres == DO_BIN_MATCH_OK) {
+ BIF_RET(result);
+ } else {
+ BUMP_ALL_REDS(BIF_P);
+ BIF_TRAP3(&binary_match_trap_export, BIF_P, BIF_ARG_1, result,
+ BIF_ARG_3);
+ }
+}
+
+static BIF_RETTYPE binary_matches_trap(BIF_ALIST_3)
+{
+ int runres;
+ Eterm result;
+ Binary *bin = ((ProcBin *) binary_val(BIF_ARG_3))->val;
+ runres = do_binary_matches(BIF_P,BIF_ARG_1,0,0,NIL,bin,BIF_ARG_2,&result);
+ if (runres == DO_BIN_MATCH_OK) {
+ BIF_RET(result);
+ } else {
+ BUMP_ALL_REDS(BIF_P);
+ BIF_TRAP3(&binary_matches_trap_export, BIF_P, BIF_ARG_1, result,
+ BIF_ARG_3);
+ }
+}
+
+BIF_RETTYPE binary_match_3(BIF_ALIST_3)
+{
+ Uint hsstart;
+ Uint hsend;
+ Eterm *tp;
+ Eterm type;
+ Binary *bin;
+ Eterm bin_term = NIL;
+ int runres;
+ Eterm result;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ goto badarg;
+ }
+ if (parse_match_opts_list(BIF_ARG_3,BIF_ARG_1,&hsstart,&hsend)) {
+ goto badarg;
+ }
+ if (hsend == 0) {
+ BIF_RET(am_nomatch);
+ }
+ if (is_tuple(BIF_ARG_2)) {
+ tp = tuple_val(BIF_ARG_2);
+ if (arityval(*tp) != 2 || is_not_atom(tp[1])) {
+ goto badarg;
+ }
+ if (((tp[1] != am_bm) && (tp[1] != am_ac)) ||
+ !ERTS_TERM_IS_MAGIC_BINARY(tp[2])) {
+ goto badarg;
+ }
+ type = tp[1];
+ bin = ((ProcBin *) binary_val(tp[2]))->val;
+ if (type == am_bm &&
+ ERTS_MAGIC_BIN_DESTRUCTOR(bin) != cleanup_my_data_bm) {
+ goto badarg;
+ }
+ if (type == am_ac &&
+ ERTS_MAGIC_BIN_DESTRUCTOR(bin) != cleanup_my_data_ac) {
+ goto badarg;
+ }
+ bin_term = tp[2];
+ } else if (do_binary_match_compile(BIF_ARG_2,&type,&bin)) {
+ goto badarg;
+ }
+ runres = do_binary_match(BIF_P,BIF_ARG_1,hsstart,hsend,type,bin,NIL,&result);
+ if (runres == DO_BIN_MATCH_RESTART && bin_term == NIL) {
+ Eterm *hp = HAlloc(BIF_P, PROC_BIN_SIZE);
+ bin_term = erts_mk_magic_binary_term(&hp, &MSO(BIF_P), bin);
+ } else if (bin_term == NIL) {
+ erts_bin_free(bin);
+ }
+ switch (runres) {
+ case DO_BIN_MATCH_OK:
+ BIF_RET(result);
+ case DO_BIN_MATCH_RESTART:
+ BUMP_ALL_REDS(BIF_P);
+ BIF_TRAP3(&binary_match_trap_export, BIF_P, BIF_ARG_1, result, bin_term);
+ default:
+ goto badarg;
+ }
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+BIF_RETTYPE binary_matches_3(BIF_ALIST_3)
+{
+ Uint hsstart, hsend;
+ Eterm *tp;
+ Eterm type;
+ Binary *bin;
+ Eterm bin_term = NIL;
+ int runres;
+ Eterm result;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ goto badarg;
+ }
+ if (parse_match_opts_list(BIF_ARG_3,BIF_ARG_1,&hsstart,&hsend)) {
+ goto badarg;
+ }
+ if (hsend == 0) {
+ BIF_RET(am_nomatch);
+ }
+ if (is_tuple(BIF_ARG_2)) {
+ tp = tuple_val(BIF_ARG_2);
+ if (arityval(*tp) != 2 || is_not_atom(tp[1])) {
+ goto badarg;
+ }
+ if (((tp[1] != am_bm) && (tp[1] != am_ac)) ||
+ !ERTS_TERM_IS_MAGIC_BINARY(tp[2])) {
+ goto badarg;
+ }
+ type = tp[1];
+ bin = ((ProcBin *) binary_val(tp[2]))->val;
+ if (type == am_bm &&
+ ERTS_MAGIC_BIN_DESTRUCTOR(bin) != cleanup_my_data_bm) {
+ goto badarg;
+ }
+ if (type == am_ac &&
+ ERTS_MAGIC_BIN_DESTRUCTOR(bin) != cleanup_my_data_ac) {
+ goto badarg;
+ }
+ bin_term = tp[2];
+ } else if (do_binary_match_compile(BIF_ARG_2,&type,&bin)) {
+ goto badarg;
+ }
+ runres = do_binary_matches(BIF_P,BIF_ARG_1,hsstart,hsend,type,bin,
+ NIL,&result);
+ if (runres == DO_BIN_MATCH_RESTART && bin_term == NIL) {
+ Eterm *hp = HAlloc(BIF_P, PROC_BIN_SIZE);
+ bin_term = erts_mk_magic_binary_term(&hp, &MSO(BIF_P), bin);
+ } else if (bin_term == NIL) {
+ erts_bin_free(bin);
+ }
+ switch (runres) {
+ case DO_BIN_MATCH_OK:
+ BIF_RET(result);
+ case DO_BIN_MATCH_RESTART:
+ BUMP_ALL_REDS(BIF_P);
+ BIF_TRAP3(&binary_matches_trap_export, BIF_P, BIF_ARG_1, result,
+ bin_term);
+ default:
+ goto badarg;
+ }
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+
+BIF_RETTYPE binary_match_2(BIF_ALIST_2)
+{
+ return binary_match_3(BIF_P,BIF_ARG_1,BIF_ARG_2,((Eterm) 0));
+}
+
+
+BIF_RETTYPE binary_matches_2(BIF_ALIST_2)
+{
+ return binary_matches_3(BIF_P,BIF_ARG_1,BIF_ARG_2,((Eterm) 0));
+}
+
+
+BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen)
+{
+ Uint pos;
+ Sint len;
+ size_t orig_size;
+ Eterm orig;
+ Uint offset;
+ Uint bit_offset;
+ Uint bit_size;
+ Eterm* hp;
+ ErlSubBin* sb;
+
+ if (is_not_binary(binary)) {
+ goto badarg;
+ }
+ if (!term_to_Uint(epos, &pos)) {
+ goto badarg;
+ }
+ if (!term_to_Sint(elen, &len)) {
+ goto badarg;
+ }
+ if (len < 0) {
+ Sint lentmp = -len;
+ /* overflow */
+ if (lentmp == len || lentmp < 0 || -lentmp != len) {
+ goto badarg;
+ }
+ len = lentmp;
+ if (len > pos) {
+ goto badarg;
+ }
+ pos -= len;
+ }
+ /* overflow */
+ if ((pos + len) < pos || (len > 0 && (pos + len) == pos)){
+ goto badarg;
+ }
+ if ((orig_size = binary_size(binary)) < pos ||
+ orig_size < (pos + len)) {
+ goto badarg;
+ }
+
+
+
+ hp = HAlloc(p, ERL_SUB_BIN_SIZE);
+
+ ERTS_GET_REAL_BIN(binary, orig, offset, bit_offset, bit_size);
+ sb = (ErlSubBin *) hp;
+ sb->thing_word = HEADER_SUB_BIN;
+ sb->size = len;
+ sb->offs = offset + pos;
+ sb->orig = orig;
+ sb->bitoffs = bit_offset;
+ sb->bitsize = 0;
+ sb->is_writable = 0;
+
+ BIF_RET(make_binary(sb));
+
+ badarg:
+ BIF_ERROR(p, BADARG);
+}
+
+#define ERTS_NEED_GC(p, need) ((HEAP_LIMIT((p)) - HEAP_TOP((p))) <= (need))
+
+BIF_RETTYPE erts_gc_binary_part(Process *p, Eterm *reg, Eterm live, int range_is_tuple)
+{
+ Uint pos;
+ Sint len;
+ size_t orig_size;
+ Eterm orig;
+ Uint offset;
+ Uint bit_offset;
+ Uint bit_size;
+ Eterm* hp;
+ ErlSubBin* sb;
+ Eterm binary;
+ Eterm *tp;
+ Eterm epos, elen;
+ int extra_args;
+
+
+ if (range_is_tuple) {
+ Eterm tpl = reg[live];
+ extra_args = 1;
+ if (is_not_tuple(tpl)) {
+ goto badarg;
+ }
+ tp = tuple_val(tpl);
+ if (arityval(*tp) != 2) {
+ goto badarg;
+ }
+
+ epos = tp[1];
+ elen = tp[2];
+ } else {
+ extra_args = 2;
+ epos = reg[live-1];
+ elen = reg[live];
+ }
+ binary = reg[live-extra_args];
+
+ if (is_not_binary(binary)) {
+ goto badarg;
+ }
+ if (!term_to_Uint(epos, &pos)) {
+ goto badarg;
+ }
+ if (!term_to_Sint(elen, &len)) {
+ goto badarg;
+ }
+ if (len < 0) {
+ Sint lentmp = -len;
+ /* overflow */
+ if (lentmp == len || lentmp < 0 || -lentmp != len) {
+ goto badarg;
+ }
+ len = lentmp;
+ if (len > pos) {
+ goto badarg;
+ }
+ pos -= len;
+ }
+ /* overflow */
+ if ((pos + len) < pos || (len > 0 && (pos + len) == pos)) {
+ goto badarg;
+ }
+ if ((orig_size = binary_size(binary)) < pos ||
+ orig_size < (pos + len)) {
+ goto badarg;
+ }
+
+ if (ERTS_NEED_GC(p, ERL_SUB_BIN_SIZE)) {
+ erts_garbage_collect(p, ERL_SUB_BIN_SIZE, reg, live+1-extra_args); /* I don't need the tuple
+ or indices any more */
+ binary = reg[live-extra_args];
+ }
+
+ hp = p->htop;
+ p->htop += ERL_SUB_BIN_SIZE;
+
+ ERTS_GET_REAL_BIN(binary, orig, offset, bit_offset, bit_size);
+
+ sb = (ErlSubBin *) hp;
+ sb->thing_word = HEADER_SUB_BIN;
+ sb->size = len;
+ sb->offs = offset + pos;
+ sb->orig = orig;
+ sb->bitoffs = bit_offset;
+ sb->bitsize = 0;
+ sb->is_writable = 0;
+
+ BIF_RET(make_binary(sb));
+
+ badarg:
+ BIF_ERROR(p, BADARG);
+}
+/*************************************************************
+ * The actual guard BIFs are in erl_bif_guard.c
+ * but the implementation of both the non-gc and the gc
+ * variants are here. Note that the functions are named so that they do
+ * not clash with the guard bif's erlang:binary_part/2,3
+ *************************************************************/
+
+BIF_RETTYPE binary_binary_part_3(BIF_ALIST_3)
+{
+ return erts_binary_part(BIF_P,BIF_ARG_1,BIF_ARG_2, BIF_ARG_3);
+}
+
+BIF_RETTYPE binary_binary_part_2(BIF_ALIST_2)
+{
+ Eterm *tp;
+ if (is_not_tuple(BIF_ARG_2)) {
+ goto badarg;
+ }
+ tp = tuple_val(BIF_ARG_2);
+ if (arityval(*tp) != 2) {
+ goto badarg;
+ }
+ return erts_binary_part(BIF_P,BIF_ARG_1,tp[1], tp[2]);
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+typedef struct {
+ int type; /* CL_TYPE_XXX */
+ byte *temp_alloc; /* Used for erts_get/free_aligned, i.e. CL_TYPE_ALIGNED */
+ unsigned char *buff; /* Used for all types, malloced if CL_TYPE_HEAP */
+ Uint bufflen; /* The length (in bytes) of buffer */
+} CommonData;
+
+#define COMMON_LOOP_FACTOR 10
+
+#define DIRECTION_PREFIX 0
+#define DIRECTION_SUFFIX 1
+
+#define CL_OK 0
+#define CL_RESTART 1
+
+/* The type field in the above structure */
+#define CL_TYPE_EMPTY 0 /* End of array */
+#define CL_TYPE_HEAP 1
+#define CL_TYPE_ALIGNED 2
+#define CL_TYPE_COMMON 3 /* emacsulated */
+#define CL_TYPE_HEAP_NOALLOC 4 /* Will need allocating when trapping */
+
+
+static int do_search_forward(CommonData *cd, Uint *posp, Uint *redsp)
+{
+ Uint pos = *posp;
+ Sint reds = (Sint) *redsp;
+ int i;
+ unsigned char current = 0;
+
+ for(;;) {
+ for(i = 0; cd[i].type != CL_TYPE_EMPTY; ++i) {
+ if (pos >= cd[i].bufflen) {
+ *posp = pos;
+ if (reds > 0) {
+ *redsp = (Uint) reds;
+ } else {
+ *redsp = 0;
+ }
+ return CL_OK;
+ }
+ if (i == 0) {
+ current = cd[i].buff[pos];
+ } else {
+ if (cd[i].buff[pos] != current) {
+ *posp = pos;
+ if (reds > 0) {
+ *redsp = (Uint) reds;
+ } else {
+ *redsp = 0;
+ }
+ return CL_OK;
+ }
+ }
+ --reds;
+ }
+ ++pos;
+ if (reds <= 0) {
+ *posp = pos;
+ *redsp = 0;
+ return CL_RESTART;
+ }
+ }
+}
+static int do_search_backward(CommonData *cd, Uint *posp, Uint *redsp)
+{
+ Uint pos = *posp;
+ Sint reds = (Sint) *redsp;
+ int i;
+ unsigned char current = 0;
+
+ for(;;) {
+ for(i = 0; cd[i].type != CL_TYPE_EMPTY; ++i) {
+ if (pos >= cd[i].bufflen) {
+ *posp = pos;
+ if (reds > 0) {
+ *redsp = (Uint) reds;
+ } else {
+ *redsp = 0;
+ }
+ return CL_OK;
+ }
+ if (i == 0) {
+ current = cd[i].buff[cd[i].bufflen - 1 - pos];
+ } else {
+ if (cd[i].buff[cd[i].bufflen - 1 - pos] != current) {
+ *posp = pos;
+ if (reds > 0) {
+ *redsp = (Uint) reds;
+ } else {
+ *redsp = 0;
+ }
+ return CL_OK;
+ }
+ }
+ --reds;
+ }
+ ++pos;
+ if (reds <= 0) {
+ *posp = pos;
+ *redsp = 0;
+ return CL_RESTART;
+ }
+ }
+}
+
+static void cleanup_common_data(Binary *bp)
+{
+ int i;
+ CommonData *cd;
+ cd = (CommonData *) ERTS_MAGIC_BIN_DATA(bp);
+ for (i=0;cd[i].type != CL_TYPE_EMPTY;++i) {
+ switch (cd[i].type) {
+ case CL_TYPE_HEAP:
+ erts_free(ERTS_ALC_T_BINARY_BUFFER,cd[i].buff);
+ break;
+ case CL_TYPE_ALIGNED:
+ erts_free_aligned_binary_bytes_extra(cd[i].temp_alloc, ERTS_ALC_T_BINARY_BUFFER);
+ break;
+ default:
+ break;
+ }
+ }
+ return;
+}
+
+static BIF_RETTYPE do_longest_common(Process *p, Eterm list, int direction)
+{
+ Eterm l = list;
+ int n = 0;
+ Binary *mb;
+ CommonData *cd;
+ int i = 0;
+ Uint reds = get_reds(p, COMMON_LOOP_FACTOR);
+ Uint save_reds = reds;
+ int res;
+ Export *trapper;
+ Uint pos;
+ Eterm epos;
+ Eterm *hp;
+ Eterm bin_term;
+ Eterm b;
+
+ /* First just count the number of binaries */
+ while (is_list(l)) {
+ b = CAR(list_val(l));
+ if (!is_binary(b)) {
+ goto badarg;
+ }
+ ++n;
+ l = CDR(list_val(l));
+ }
+ if (l != NIL || n == 0) {
+ goto badarg;
+ }
+
+ /* OK, now create a buffer of the right size, we can do a magic binary right away,
+ that's not too costly. */
+ mb = erts_create_magic_binary((n+1)*sizeof(CommonData),cleanup_common_data);
+ cd = (CommonData *) ERTS_MAGIC_BIN_DATA(mb);
+ l = list;
+ while (is_list(l)) {
+ Uint bitoffs;
+ Uint bitsize;
+ Uint offset;
+ Eterm real_bin;
+ ProcBin* pb;
+
+ cd[i].type = CL_TYPE_EMPTY;
+ b = CAR(list_val(l));
+ ERTS_GET_REAL_BIN(b, real_bin, offset, bitoffs, bitsize);
+ if (bitsize != 0) {
+ erts_bin_free(mb);
+ goto badarg;
+ }
+ cd[i].bufflen = binary_size(b);
+ cd[i].temp_alloc = NULL;
+ if (*(binary_val(real_bin)) == HEADER_PROC_BIN) {
+ pb = (ProcBin *) binary_val(real_bin);
+ if (pb->flags) {
+ erts_emasculate_writable_binary(pb);
+ }
+ cd[i].buff = erts_get_aligned_binary_bytes_extra(b, &(cd[i].temp_alloc),
+ ERTS_ALC_T_BINARY_BUFFER,0);
+ cd[i].type = (cd[i].temp_alloc != NULL) ? CL_TYPE_ALIGNED : CL_TYPE_COMMON;
+ } else { /* Heap binary */
+ cd[i].buff = erts_get_aligned_binary_bytes_extra(b, &(cd[i].temp_alloc),
+ ERTS_ALC_T_BINARY_BUFFER,0);
+ /* CL_TYPE_HEAP_NOALLOC means you have to copy if trapping */
+ cd[i].type = (cd[i].temp_alloc != NULL) ? CL_TYPE_ALIGNED : CL_TYPE_HEAP_NOALLOC;
+ }
+ ++i;
+ l = CDR(list_val(l));
+ }
+ cd[i].type = CL_TYPE_EMPTY;
+#if defined(DEBUG) || defined(VALGRIND)
+ cd[i].temp_alloc = NULL;
+ cd[i].buff = NULL;
+ cd[i].bufflen = 0;
+#endif
+
+ pos = 0;
+ if (direction == DIRECTION_PREFIX) {
+ trapper = &binary_longest_prefix_trap_export;
+ res = do_search_forward(cd,&pos,&reds);
+ } else {
+ ASSERT(direction == DIRECTION_SUFFIX);
+ trapper = &binary_longest_suffix_trap_export;
+ res = do_search_backward(cd,&pos,&reds);
+ }
+ epos = erts_make_integer(pos,p);
+ if (res == CL_OK) {
+ erts_bin_free(mb);
+ BUMP_REDS(p, (save_reds - reds) / COMMON_LOOP_FACTOR);
+ BIF_RET(epos);
+ } else {
+ ASSERT(res == CL_RESTART);
+ /* Copy all heap binaries that are not already copied (aligned) */
+ for(i = 0; i < n; ++i) {
+ if (cd[i].type == CL_TYPE_HEAP_NOALLOC) {
+ unsigned char *tmp = cd[i].buff;
+ cd[i].buff = erts_alloc(ERTS_ALC_T_BINARY_BUFFER, cd[i].bufflen);
+ memcpy(cd[i].buff,tmp,cd[i].bufflen);
+ cd[i].type = CL_TYPE_HEAP;
+ }
+ }
+ hp = HAlloc(p, PROC_BIN_SIZE);
+ bin_term = erts_mk_magic_binary_term(&hp, &MSO(p), mb);
+ BUMP_ALL_REDS(p);
+ BIF_TRAP3(trapper, p, bin_term, epos,list);
+ }
+ badarg:
+ BIF_ERROR(p,BADARG);
+}
+
+static BIF_RETTYPE do_longest_common_trap(Process *p, Eterm bin_term, Eterm current_pos,
+ Eterm orig_list, int direction)
+{
+ Uint reds = get_reds(p, COMMON_LOOP_FACTOR);
+ Uint save_reds = reds;
+ Uint pos;
+ Binary *bin;
+ CommonData *cd;
+ int res;
+ Eterm epos;
+ Export *trapper;
+
+#ifdef DEBUG
+ int r;
+ r = term_to_Uint(current_pos, &pos);
+ ASSERT(r != 0);
+#else
+ term_to_Uint(current_pos, &pos);
+#endif
+ ASSERT(ERTS_TERM_IS_MAGIC_BINARY(bin_term));
+ bin = ((ProcBin *) binary_val(bin_term))->val;
+ cd = (CommonData *) ERTS_MAGIC_BIN_DATA(bin);
+ if (direction == DIRECTION_PREFIX) {
+ trapper = &binary_longest_prefix_trap_export;
+ res = do_search_forward(cd,&pos,&reds);
+ } else {
+ ASSERT(direction == DIRECTION_SUFFIX);
+ trapper = &binary_longest_suffix_trap_export;
+ res = do_search_backward(cd,&pos,&reds);
+ }
+ epos = erts_make_integer(pos,p);
+ if (res == CL_OK) {
+ BUMP_REDS(p, (save_reds - reds) / COMMON_LOOP_FACTOR);
+ BIF_RET(epos);
+ } else {
+ ASSERT(res == CL_RESTART);
+ /* Copy all heap binaries that are not already copied (aligned) */
+ BUMP_ALL_REDS(p);
+ BIF_TRAP3(trapper, p, bin_term, epos, orig_list);
+ }
+}
+
+static BIF_RETTYPE binary_longest_prefix_trap(BIF_ALIST_3)
+{
+ return do_longest_common_trap(BIF_P,BIF_ARG_1,BIF_ARG_2,BIF_ARG_3,DIRECTION_PREFIX);
+}
+
+static BIF_RETTYPE binary_longest_suffix_trap(BIF_ALIST_3)
+{
+ return do_longest_common_trap(BIF_P,BIF_ARG_1,BIF_ARG_2,BIF_ARG_3,DIRECTION_SUFFIX);
+}
+
+BIF_RETTYPE binary_longest_common_prefix_1(BIF_ALIST_1)
+{
+ return do_longest_common(BIF_P,BIF_ARG_1,DIRECTION_PREFIX);
+}
+
+BIF_RETTYPE binary_longest_common_suffix_1(BIF_ALIST_1)
+{
+ return do_longest_common(BIF_P,BIF_ARG_1,DIRECTION_SUFFIX);
+}
+
+BIF_RETTYPE binary_first_1(BIF_ALIST_1)
+{
+ byte* bytes;
+ Uint byte_size;
+ Uint bit_offs;
+ Uint bit_size;
+ Uint res;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ goto badarg;
+ }
+ byte_size = binary_size(BIF_ARG_1);
+ if (!byte_size) {
+ goto badarg;
+ }
+ ERTS_GET_BINARY_BYTES(BIF_ARG_1,bytes,bit_offs,bit_size);
+ if (bit_size) {
+ goto badarg;
+ }
+ if (bit_offs) {
+ res = ((((Uint) bytes[0]) << bit_offs) | (((Uint) bytes[1]) >> (8-bit_offs))) & 0xFF;
+ } else {
+ res = bytes[0];
+ }
+ BIF_RET(make_small(res));
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+BIF_RETTYPE binary_last_1(BIF_ALIST_1)
+{
+ byte* bytes;
+ Uint byte_size;
+ Uint bit_offs;
+ Uint bit_size;
+ Uint res;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ goto badarg;
+ }
+ byte_size = binary_size(BIF_ARG_1);
+ if (!byte_size) {
+ goto badarg;
+ }
+ ERTS_GET_BINARY_BYTES(BIF_ARG_1,bytes,bit_offs,bit_size);
+ if (bit_size) {
+ goto badarg;
+ }
+ if (bit_offs) {
+ res = ((((Uint) bytes[byte_size-1]) << bit_offs) |
+ (((Uint) bytes[byte_size]) >> (8-bit_offs))) & 0xFF;
+ } else {
+ res = bytes[byte_size-1];
+ }
+ BIF_RET(make_small(res));
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+BIF_RETTYPE binary_at_2(BIF_ALIST_2)
+{
+ byte* bytes;
+ Uint byte_size;
+ Uint bit_offs;
+ Uint bit_size;
+ Uint res;
+ Uint index;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ goto badarg;
+ }
+ byte_size = binary_size(BIF_ARG_1);
+ if (!byte_size) {
+ goto badarg;
+ }
+ if (!term_to_Uint(BIF_ARG_2, &index)) {
+ goto badarg;
+ }
+ if (index >= byte_size) {
+ goto badarg;
+ }
+ ERTS_GET_BINARY_BYTES(BIF_ARG_1,bytes,bit_offs,bit_size);
+ if (bit_size) {
+ goto badarg;
+ }
+ if (bit_offs) {
+ res = ((((Uint) bytes[index]) << bit_offs) |
+ (((Uint) bytes[index+1]) >> (8-bit_offs))) & 0xFF;
+ } else {
+ res = bytes[index];
+ }
+ BIF_RET(make_small(res));
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+#define BIN_TO_LIST_OK 0
+#define BIN_TO_LIST_TRAP 1
+/* No badarg, checked before call */
+
+#define BIN_TO_LIST_LOOP_FACTOR 10
+
+static int do_bin_to_list(Process *p, byte *bytes, Uint bit_offs,
+ Uint start, Sint *lenp, Eterm *termp)
+{
+ Uint reds = get_reds(p, BIN_TO_LIST_LOOP_FACTOR); /* reds can never be 0 */
+ Uint len = *lenp;
+ Uint loops;
+ Eterm *hp;
+ Eterm term = *termp;
+ Uint n;
+
+ ASSERT(reds > 0);
+
+ loops = MIN(reds,len);
+
+ BUMP_REDS(p, loops / BIN_TO_LIST_LOOP_FACTOR);
+
+ hp = HAlloc(p,2*loops);
+ while (loops--) {
+ --len;
+ if (bit_offs) {
+ n = ((((Uint) bytes[start+len]) << bit_offs) |
+ (((Uint) bytes[start+len+1]) >> (8-bit_offs))) & 0xFF;
+ } else {
+ n = bytes[start+len];
+ }
+
+ term = CONS(hp,make_small(n),term);
+ hp +=2;
+ }
+ *termp = term;
+ *lenp = len;
+ if (len) {
+ BUMP_ALL_REDS(p);
+ return BIN_TO_LIST_TRAP;
+ }
+ return BIN_TO_LIST_OK;
+}
+
+
+static BIF_RETTYPE do_trap_bin_to_list(Process *p, Eterm binary,
+ Uint start, Sint len, Eterm sofar)
+{
+ Eterm *hp;
+ Eterm blob;
+
+ hp = HAlloc(p,3);
+ hp[0] = make_pos_bignum_header(2);
+ hp[1] = start;
+ hp[2] = (Uint) len;
+ blob = make_big(hp);
+ BIF_TRAP3(&binary_bin_to_list_trap_export, p, binary, blob, sofar);
+}
+
+static BIF_RETTYPE binary_bin_to_list_trap(BIF_ALIST_3)
+{
+ Eterm *ptr;
+ Uint start;
+ Sint len;
+ byte *bytes;
+ Uint bit_offs;
+ Uint bit_size;
+ Eterm res = BIF_ARG_3;
+
+ ptr = big_val(BIF_ARG_2);
+ start = ptr[1];
+ len = (Sint) ptr[2];
+
+ ERTS_GET_BINARY_BYTES(BIF_ARG_1,bytes,bit_offs,bit_size);
+ if (do_bin_to_list(BIF_P, bytes, bit_offs, start, &len, &res) ==
+ BIN_TO_LIST_OK) {
+ BIF_RET(res);
+ }
+ return do_trap_bin_to_list(BIF_P,BIF_ARG_1,start,len,res);
+}
+
+static BIF_RETTYPE binary_bin_to_list_common(Process *p,
+ Eterm bin,
+ Eterm epos,
+ Eterm elen)
+{
+ Uint pos;
+ Sint len;
+ size_t sz;
+ byte *bytes;
+ Uint bit_offs;
+ Uint bit_size;
+ Eterm res = NIL;
+
+ if (is_not_binary(bin)) {
+ goto badarg;
+ }
+ if (!term_to_Uint(epos, &pos)) {
+ goto badarg;
+ }
+ if (!term_to_Sint(elen, &len)) {
+ goto badarg;
+ }
+ if (len < 0) {
+ Sint lentmp = -len;
+ /* overflow */
+ if (lentmp == len || lentmp < 0 || -lentmp != len) {
+ goto badarg;
+ }
+ len = lentmp;
+ if (len > pos) {
+ goto badarg;
+ }
+ pos -= len;
+ }
+ /* overflow */
+ if ((pos + len) < pos || (len > 0 && (pos + len) == pos)) {
+ goto badarg;
+ }
+ sz = binary_size(bin);
+
+ if (pos+len > sz) {
+ goto badarg;
+ }
+ ERTS_GET_BINARY_BYTES(bin,bytes,bit_offs,bit_size);
+ if (bit_size != 0) {
+ goto badarg;
+ }
+ if(do_bin_to_list(p, bytes, bit_offs, pos, &len, &res) ==
+ BIN_TO_LIST_OK) {
+ BIF_RET(res);
+ }
+ return do_trap_bin_to_list(p,bin,pos,len,res);
+
+ badarg:
+ BIF_ERROR(p,BADARG);
+}
+
+BIF_RETTYPE binary_bin_to_list_3(BIF_ALIST_3)
+{
+ return binary_bin_to_list_common(BIF_P,BIF_ARG_1,BIF_ARG_2,BIF_ARG_3);
+}
+
+BIF_RETTYPE binary_bin_to_list_2(BIF_ALIST_2)
+{
+ Eterm *tp;
+
+ if (is_not_tuple(BIF_ARG_2)) {
+ goto badarg;
+ }
+ tp = tuple_val(BIF_ARG_2);
+ if (arityval(*tp) != 2) {
+ goto badarg;
+ }
+ return binary_bin_to_list_common(BIF_P,BIF_ARG_1,tp[1],tp[2]);
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+BIF_RETTYPE binary_bin_to_list_1(BIF_ALIST_1)
+{
+ Uint pos = 0;
+ Sint len;
+ byte *bytes;
+ Uint bit_offs;
+ Uint bit_size;
+ Eterm res = NIL;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ goto badarg;
+ }
+ len = binary_size(BIF_ARG_1);
+ ERTS_GET_BINARY_BYTES(BIF_ARG_1,bytes,bit_offs,bit_size);
+ if (bit_size != 0) {
+ goto badarg;
+ }
+ if(do_bin_to_list(BIF_P, bytes, bit_offs, pos, &len, &res) ==
+ BIN_TO_LIST_OK) {
+ BIF_RET(res);
+ }
+ return do_trap_bin_to_list(BIF_P,BIF_ARG_1,pos,len,res);
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+/*
+ * Ok, erlang:list_to_binary does not interrupt, and we really don't want
+ * an alternative implementation for the exact same thing, why we
+ * have descided to use the old non-restarting implementation for now.
+ * In reality, there are seldom many iterations involved in doing this, so the
+ * problem of long-running bifs is not really that big in this case.
+ * So, for now we use the old implementation also in the module binary.
+ */
+
+BIF_RETTYPE binary_list_to_bin_1(BIF_ALIST_1)
+{
+ return erts_list_to_binary_bif(BIF_P, BIF_ARG_1);
+}
+
+typedef struct {
+ Uint times_left;
+ Uint source_size;
+ int source_type;
+ byte *source;
+ byte *temp_alloc;
+ Uint result_pos;
+ Binary *result;
+} CopyBinState;
+
+#define BC_TYPE_EMPTY 0
+#define BC_TYPE_HEAP 1
+#define BC_TYPE_ALIGNED 2 /* May or may not point to (emasculated) binary, temp_alloc field is set
+ so that erts_free_aligned_binary_bytes_extra can handle either */
+
+
+#define BINARY_COPY_LOOP_FACTOR 100
+
+static void cleanup_copy_bin_state(Binary *bp)
+{
+ CopyBinState *cbs = (CopyBinState *) ERTS_MAGIC_BIN_DATA(bp);
+ if (cbs->result != NULL) {
+ erts_bin_free(cbs->result);
+ cbs->result = NULL;
+ }
+ switch (cbs->source_type) {
+ case BC_TYPE_HEAP:
+ erts_free(ERTS_ALC_T_BINARY_BUFFER,cbs->source);
+ break;
+ case BC_TYPE_ALIGNED:
+ erts_free_aligned_binary_bytes_extra(cbs->temp_alloc,
+ ERTS_ALC_T_BINARY_BUFFER);
+ break;
+ default:
+ /* otherwise do nothing */
+ break;
+ }
+ cbs->source_type = BC_TYPE_EMPTY;
+}
+
+/*
+ * Binary *erts_bin_nrml_alloc(Uint size);
+ * Binary *erts_bin_realloc(Binary *bp, Uint size);
+ * void erts_bin_free(Binary *bp);
+ */
+static BIF_RETTYPE do_binary_copy(Process *p, Eterm bin, Eterm en)
+{
+ Uint n;
+ byte *bytes;
+ Uint bit_offs;
+ Uint bit_size;
+ size_t size;
+ Uint reds = get_reds(p, BINARY_COPY_LOOP_FACTOR);
+ Uint target_size;
+ byte *t;
+ Uint pos;
+
+
+ if (is_not_binary(bin)) {
+ goto badarg;
+ }
+ if (!term_to_Uint(en, &n)) {
+ goto badarg;
+ }
+ if (!n) {
+ Eterm res_term = erts_new_heap_binary(p,NULL,0,&bytes);
+ BIF_RET(res_term);
+ }
+ ERTS_GET_BINARY_BYTES(bin,bytes,bit_offs,bit_size);
+ if (bit_size != 0) {
+ goto badarg;
+ }
+
+ size = binary_size(bin);
+ target_size = size * n;
+
+ if ((target_size - size) >= reds) {
+ Eterm orig;
+ Uint offset;
+ Uint bit_offset;
+ Uint bit_size;
+ CopyBinState *cbs;
+ Eterm *hp;
+ Eterm trap_term;
+ int i;
+
+ /* We will trap, set up the structure for trapping right away */
+ Binary *mb = erts_create_magic_binary(sizeof(CopyBinState),
+ cleanup_copy_bin_state);
+ cbs = ERTS_MAGIC_BIN_DATA(mb);
+
+ cbs->temp_alloc = NULL;
+ cbs->source = NULL;
+
+ ERTS_GET_REAL_BIN(bin, orig, offset, bit_offset, bit_size);
+ if (*(binary_val(orig)) == HEADER_PROC_BIN) {
+ ProcBin* pb = (ProcBin *) binary_val(orig);
+ if (pb->flags) {
+ erts_emasculate_writable_binary(pb);
+ }
+ cbs->source =
+ erts_get_aligned_binary_bytes_extra(bin,
+ &(cbs->temp_alloc),
+ ERTS_ALC_T_BINARY_BUFFER,
+ 0);
+ cbs->source_type = BC_TYPE_ALIGNED;
+ } else { /* Heap binary */
+ cbs->source =
+ erts_get_aligned_binary_bytes_extra(bin,
+ &(cbs->temp_alloc),
+ ERTS_ALC_T_BINARY_BUFFER,
+ 0);
+ if (!(cbs->temp_alloc)) { /* alignment not needed, need to copy */
+ byte *tmp = erts_alloc(ERTS_ALC_T_BINARY_BUFFER,size);
+ memcpy(tmp,cbs->source,size);
+ cbs->source = tmp;
+ cbs->source_type = BC_TYPE_HEAP;
+ } else {
+ cbs->source_type = BC_TYPE_ALIGNED;
+ }
+ }
+ cbs->result = erts_bin_nrml_alloc(target_size); /* Always offheap
+ if trapping */
+ cbs->result->flags = 0;
+ cbs->result->orig_size = target_size;
+ erts_refc_init(&(cbs->result->refc), 1);
+ t = (byte *) cbs->result->orig_bytes; /* No offset or anything */
+ pos = 0;
+ i = 0;
+ while (pos < reds) {
+ memcpy(t+pos,cbs->source, size);
+ pos += size;
+ ++i;
+ }
+ cbs->source_size = size;
+ cbs->result_pos = pos;
+ cbs->times_left = n-i;
+ hp = HAlloc(p,PROC_BIN_SIZE);
+ trap_term = erts_mk_magic_binary_term(&hp, &MSO(p), mb);
+ BUMP_ALL_REDS(p);
+ BIF_TRAP2(&binary_copy_trap_export, p, bin, trap_term);
+ } else {
+ Eterm res_term;
+ byte *temp_alloc = NULL;
+ byte *source =
+ erts_get_aligned_binary_bytes(bin,
+ &temp_alloc);
+ if (target_size <= ERL_ONHEAP_BIN_LIMIT) {
+ res_term = erts_new_heap_binary(p,NULL,target_size,&t);
+ } else {
+ res_term = erts_new_mso_binary(p,NULL,target_size);
+ t = ((ProcBin *) binary_val(res_term))->bytes;
+ }
+ pos = 0;
+ while (pos < target_size) {
+ memcpy(t+pos,source, size);
+ pos += size;
+ }
+ erts_free_aligned_binary_bytes(temp_alloc);
+ BUMP_REDS(p,pos / BINARY_COPY_LOOP_FACTOR);
+ BIF_RET(res_term);
+ }
+ badarg:
+ BIF_ERROR(p,BADARG);
+}
+
+BIF_RETTYPE binary_copy_trap(BIF_ALIST_2)
+{
+ Uint n;
+ size_t size;
+ Uint reds = get_reds(BIF_P, BINARY_COPY_LOOP_FACTOR);
+ byte *t;
+ Uint pos;
+ Binary *mb = ((ProcBin *) binary_val(BIF_ARG_2))->val;
+ CopyBinState *cbs = (CopyBinState *) ERTS_MAGIC_BIN_DATA(mb);
+ Uint opos;
+
+ /* swapout... */
+ n = cbs->times_left;
+ size = cbs->source_size;
+ opos = pos = cbs->result_pos;
+ t = (byte *) cbs->result->orig_bytes; /* "well behaved" binary */
+ if ((n-1) * size >= reds) {
+ Uint i = 0;
+ while ((pos - opos) < reds) {
+ memcpy(t+pos,cbs->source, size);
+ pos += size;
+ ++i;
+ }
+ cbs->result_pos = pos;
+ cbs->times_left -= i;
+ BUMP_ALL_REDS(BIF_P);
+ BIF_TRAP2(&binary_copy_trap_export, BIF_P, BIF_ARG_1, BIF_ARG_2);
+ } else {
+ Binary *save;
+ ProcBin* pb;
+ Uint target_size = cbs->result->orig_size;
+ while (pos < target_size) {
+ memcpy(t+pos,cbs->source, size);
+ pos += size;
+ }
+ save = cbs->result;
+ cbs->result = NULL;
+ cleanup_copy_bin_state(mb); /* now cbs is dead */
+ pb = (ProcBin *) HAlloc(BIF_P, PROC_BIN_SIZE);
+ pb->thing_word = HEADER_PROC_BIN;
+ pb->size = target_size;
+ pb->next = MSO(BIF_P).mso;
+ MSO(BIF_P).mso = pb;
+ pb->val = save;
+ pb->bytes = t;
+ pb->flags = 0;
+
+ MSO(BIF_P).overhead += target_size / sizeof(Eterm);
+ BUMP_REDS(BIF_P,(pos - opos) / BINARY_COPY_LOOP_FACTOR);
+
+ BIF_RET(make_binary(pb));
+ }
+}
+
+
+BIF_RETTYPE binary_copy_1(BIF_ALIST_1)
+{
+ return do_binary_copy(BIF_P,BIF_ARG_1,make_small(1));
+}
+
+BIF_RETTYPE binary_copy_2(BIF_ALIST_2)
+{
+ return do_binary_copy(BIF_P,BIF_ARG_1,BIF_ARG_2);
+}
+
+BIF_RETTYPE binary_referenced_byte_size_1(BIF_ALIST_1)
+{
+ ErlSubBin *sb;
+ ProcBin *pb;
+ Eterm res;
+ Eterm bin = BIF_ARG_1;
+
+ if (is_not_binary(BIF_ARG_1)) {
+ BIF_ERROR(BIF_P,BADARG);
+ }
+ sb = (ErlSubBin *) binary_val(bin);
+ if (sb->thing_word == HEADER_SUB_BIN) {
+ bin = sb->orig;
+ }
+ pb = (ProcBin *) binary_val(bin);
+ if (pb->thing_word == HEADER_PROC_BIN) {
+ res = erts_make_integer((Uint) pb->val->orig_size, BIF_P); /* XXX:PaN Halfword? orig_size is a long */
+ } else { /* heap binary */
+ res = erts_make_integer((Uint) ((ErlHeapBin *) pb)->size, BIF_P);
+ }
+ BIF_RET(res);
+}
+
+#define END_BIG 0
+#define END_SMALL 1
+
+#ifdef WORDS_BIGENDIAN
+#define END_NATIVE END_BIG
+#else
+#define END_NATIVE END_SMALL
+#endif
+
+static int get_need(Uint u) {
+#if defined(ARCH_64) && !HALFWORD_HEAP
+ if (u > 0xFFFFFFFFUL) {
+ if (u > 0xFFFFFFFFFFFFUL) {
+ if (u > 0xFFFFFFFFFFFFFFUL) {
+ return 8;
+ }
+ return 7;
+ }
+ if (u > 0xFFFFFFFFFFUL) {
+ return 6;
+ }
+ return 5;
+ }
+#endif
+ if (u > 0xFFFFUL) {
+ if (u > 0xFFFFFFUL) {
+ return 4;
+ }
+ return 3;
+ }
+ if (u > 0xFFUL) {
+ return 2;
+ }
+ return 1;
+}
+
+static BIF_RETTYPE do_encode_unsigned(Process *p, Eterm uns, Eterm endianess)
+{
+ Eterm res;
+ if ((is_not_small(uns) && is_not_big(uns)) || is_not_atom(endianess) ||
+ (endianess != am_big && endianess != am_little)) {
+ goto badarg;
+ }
+ if (is_small(uns)) {
+ Sint x = signed_val(uns);
+ Uint u;
+ int n,i;
+ byte *b;
+
+ if (x < 0) {
+ goto badarg;
+ }
+
+ u = (Uint) x;
+ n = get_need(u);
+ ASSERT(n <= ERL_ONHEAP_BIN_LIMIT);
+ res = erts_new_heap_binary(p, NULL, n, &b);
+ if (endianess == am_big) {
+ for(i=n-1;i>=0;--i) {
+ b[i] = u & 0xFF;
+ u >>= 8;
+ }
+ } else {
+ for(i=0;i<n;++i) {
+ b[i] = u & 0xFF;
+ u >>= 8;
+ }
+ }
+ BIF_RET(res);
+ } else {
+ /* Big */
+ Eterm *bigp = big_val(uns);
+ Uint n;
+ dsize_t num_parts = BIG_SIZE(bigp);
+ Eterm res;
+ byte *b;
+ ErtsDigit d;
+
+ if(BIG_SIGN(bigp)) {
+ goto badarg;
+ }
+ n = (num_parts-1)*sizeof(ErtsDigit)+get_need(BIG_DIGIT(bigp,(num_parts-1)));
+ if (n <= ERL_ONHEAP_BIN_LIMIT) {
+ res = erts_new_heap_binary(p,NULL,n,&b);
+ } else {
+ res = erts_new_mso_binary(p,NULL,n);
+ b = ((ProcBin *) binary_val(res))->bytes;
+ }
+
+ if (endianess == am_big) {
+ Sint i,j;
+ j = 0;
+ d = BIG_DIGIT(bigp,0);
+ for (i=n-1;i>=0;--i) {
+ b[i] = d & 0xFF;
+ if (!((++j) % sizeof(ErtsDigit))) {
+ d = BIG_DIGIT(bigp,j / sizeof(ErtsDigit));
+ } else {
+ d >>= 8;
+ }
+ }
+ } else {
+ Sint i,j;
+ j = 0;
+ d = BIG_DIGIT(bigp,0);
+ for (i=0;i<n;++i) {
+ b[i] = d & 0xFF;
+ if (!((++j) % sizeof(ErtsDigit))) {
+ d = BIG_DIGIT(bigp,j / sizeof(ErtsDigit));
+ } else {
+ d >>= 8;
+ }
+ }
+
+ }
+ BIF_RET(res);
+ }
+ badarg:
+ BIF_ERROR(p,BADARG);
+}
+
+static BIF_RETTYPE do_decode_unsigned(Process *p, Eterm uns, Eterm endianess)
+{
+ byte *bytes;
+ Uint bitoffs, bitsize;
+ Uint size;
+ Eterm res;
+
+ if (is_not_binary(uns) || is_not_atom(endianess) ||
+ (endianess != am_big && endianess != am_little)) {
+ goto badarg;
+ }
+ ERTS_GET_BINARY_BYTES(uns, bytes, bitoffs, bitsize);
+ if (bitsize != 0) {
+ goto badarg;
+ }
+ /* align while rolling */
+ size = binary_size(uns);
+ if (bitoffs) {
+ if (endianess == am_big) {
+ while (size && (((((Uint) bytes[0]) << bitoffs) |
+ (((Uint) bytes[1]) >> (8-bitoffs))) & 0xFF) == 0) {
+ ++bytes;
+ --size;
+ }
+ } else {
+ while(size &&
+ (((((Uint) bytes[size-1]) << bitoffs) |
+ (((Uint) bytes[size]) >> (8-bitoffs))) & 0xFF) == 0) {
+ --size;
+ }
+ }
+ } else {
+ if (endianess == am_big) {
+ while (size && *bytes == 0) {
+ ++bytes;
+ --size;
+ }
+ } else {
+ while(size && bytes[size-1] == 0) {
+ --size;
+ }
+ }
+ }
+ if (!size) {
+ BIF_RET(make_small(0));
+ }
+
+ if (size <= sizeof(Uint)) {
+ Uint u = 0;
+ Sint i;
+
+ if (endianess == am_big) {
+ if (bitoffs) {
+ for(i=0;i<size;++i) {
+ u <<=8;
+ u |= (((((Uint) bytes[i]) << bitoffs) |
+ (((Uint) bytes[i+1]) >> (8-bitoffs))) & 0xFF);
+ }
+ } else {
+ for(i=0;i<size;++i) {
+ u <<=8;
+ u |= bytes[i];
+ }
+ }
+ } else {
+
+ if (bitoffs) {
+ for(i=size-1;i>=0;--i) {
+ u <<=8;
+ u |= (((((Uint) bytes[i]) << bitoffs) |
+ (((Uint) bytes[i+1]) >> (8-bitoffs))) & 0xFF);
+ }
+ } else {
+ for(i=size-1;i>=0;--i) {
+ u <<=8;
+ u |= bytes[i];
+ }
+ }
+ }
+ res = erts_make_integer(u,p);
+ BIF_RET(res);
+ } else {
+ /* Assume big, as we stripped away all zeroes from the MSB part of the binary */
+ dsize_t num_parts = size / sizeof(ErtsDigit) + !!(size % sizeof(ErtsDigit));
+ Eterm *bigp;
+
+ bigp = HAlloc(p, BIG_NEED_SIZE(num_parts));
+ *bigp = make_pos_bignum_header(num_parts);
+ res = make_big(bigp);
+
+ if (endianess == am_big) {
+ Sint i,j;
+ ErtsDigit *d;
+ j = size;
+ d = &(BIG_DIGIT(bigp,num_parts - 1));
+ *d = 0;
+ i = 0;
+ if(bitoffs) {
+ for (;;){
+ (*d) <<= 8;
+ (*d) |= (((((Uint) bytes[i]) << bitoffs) |
+ (((Uint) bytes[i+1]) >> (8-bitoffs))) & 0xFF);
+ if (++i >= size) {
+ break;
+ }
+ if (!(--j % sizeof(ErtsDigit))) {
+ --d;
+ *d = 0;
+ }
+ }
+ } else {
+ for (;;){
+ (*d) <<= 8;
+ (*d) |= bytes[i];
+ if (++i >= size) {
+ break;
+ }
+ if (!(--j % sizeof(ErtsDigit))) {
+ --d;
+ *d = 0;
+ }
+ }
+ }
+ } else {
+ Sint i,j;
+ ErtsDigit *d;
+ j = size;
+ d = &(BIG_DIGIT(bigp,num_parts - 1));
+ *d = 0;
+ i = size-1;
+ if (bitoffs) {
+ for (;;){
+ (*d) <<= 8;
+ (*d) |= (((((Uint) bytes[i]) << bitoffs) |
+ (((Uint) bytes[i+1]) >> (8-bitoffs))) & 0xFF);
+ if (--i < 0) {
+ break;
+ }
+ if (!(--j % sizeof(ErtsDigit))) {
+ --d;
+ *d = 0;
+ }
+ }
+ } else {
+ for (;;){
+ (*d) <<= 8;
+ (*d) |= bytes[i];
+ if (--i < 0) {
+ break;
+ }
+ if (!(--j % sizeof(ErtsDigit))) {
+ --d;
+ *d = 0;
+ }
+ }
+ }
+ }
+ BIF_RET(res);
+ }
+ badarg:
+ BIF_ERROR(p,BADARG);
+}
+
+BIF_RETTYPE binary_encode_unsigned_1(BIF_ALIST_1)
+{
+ return do_encode_unsigned(BIF_P,BIF_ARG_1,am_big);
+}
+
+BIF_RETTYPE binary_encode_unsigned_2(BIF_ALIST_2)
+{
+ return do_encode_unsigned(BIF_P,BIF_ARG_1,BIF_ARG_2);
+}
+
+BIF_RETTYPE binary_decode_unsigned_1(BIF_ALIST_1)
+{
+ return do_decode_unsigned(BIF_P,BIF_ARG_1,am_big);
+}
+
+BIF_RETTYPE binary_decode_unsigned_2(BIF_ALIST_2)
+{
+ return do_decode_unsigned(BIF_P,BIF_ARG_1,BIF_ARG_2);
+}
+
+/*
+ * Hard debug functions (dump) for the search structures
+ */
+
+#ifdef HARDDEBUG
+static void dump_bm_data(BMData *bm)
+{
+ int i,j;
+ erts_printf("Dumping Boyer-Moore structure.\n");
+ erts_printf("=============================\n");
+ erts_printf("Searchstring [%ld]:\n", bm->len);
+ erts_printf("<<");
+ for (i = 0; i < bm->len; ++i) {
+ if (i > 0) {
+ erts_printf(", ");
+ }
+ erts_printf("%d", (int) bm->x[i]);
+ if (bm->x[i] >= 'A') {
+ erts_printf(" ($%c)",(char) bm->x[i]);
+ }
+ }
+ erts_printf(">>\n");
+ erts_printf("GoodShift array:\n");
+ for (i = 0; i < bm->len; ++i) {
+ erts_printf("GoodShift[%d]: %ld\n", i, bm->goodshift[i]);
+ }
+ erts_printf("BadShift array:\n");
+ j = 0;
+ for (i = 0; i < ALPHABET_SIZE; i += j) {
+ for (j = 0; i + j < ALPHABET_SIZE && j < 6; ++j) {
+ erts_printf("BS[%03d]:%02ld, ", i+j, bm->badshift[i+j]);
+ }
+ erts_printf("\n");
+ }
+}
+
+static void dump_ac_node(ACNode *node, int indent, int ch) {
+ int i;
+ char *spaces = erts_alloc(ERTS_ALC_T_TMP, 10 * indent + 1);
+ memset(spaces,' ',10*indent);
+ spaces[10*indent] = '\0';
+ erts_printf("%s-> %c\n",spaces,ch);
+ erts_printf("%sId: %u\n",spaces,(unsigned) node->id);
+ erts_printf("%sD: %u\n",spaces,(unsigned)node->d);
+ erts_printf("%sFinal: %d\n",spaces,(int)node->final);
+ erts_printf("%sFail: %u\n",spaces,(unsigned)node->h->id);
+ erts_free(ERTS_ALC_T_TMP,spaces);
+ for(i=0;i<ALPHABET_SIZE;++i) {
+ if (node->g[i] != NULL && node->g[i] != node) {
+ dump_ac_node(node->g[i],indent+1,i);
+ }
+ }
+}
+
+
+static void dump_ac_trie(ACTrie *act)
+{
+ erts_printf("Aho Corasick Trie dump.\n");
+ erts_printf("=======================\n");
+ erts_printf("Node counter: %u\n", (unsigned) act->idc);
+ erts_printf("Searchstring counter: %u\n", (unsigned) act->counter);
+ erts_printf("Trie:\n");
+ dump_ac_node(act->root, 0, '0');
+ return;
+}
+#endif
diff --git a/erts/emulator/beam/erl_bif_guard.c b/erts/emulator/beam/erl_bif_guard.c
index 440b0b4f14..01e6977a2c 100644
--- a/erts/emulator/beam/erl_bif_guard.c
+++ b/erts/emulator/beam/erl_bif_guard.c
@@ -314,6 +314,30 @@ double_to_integer(Process* p, double x)
return res;
}
+/********************************************************************************
+ * binary_part guards. The actual implementation is in erl_bif_binary.c
+ ********************************************************************************/
+BIF_RETTYPE binary_part_3(BIF_ALIST_3)
+{
+ return erts_binary_part(BIF_P,BIF_ARG_1,BIF_ARG_2, BIF_ARG_3);
+}
+
+BIF_RETTYPE binary_part_2(BIF_ALIST_2)
+{
+ Eterm *tp;
+ if (is_not_tuple(BIF_ARG_2)) {
+ goto badarg;
+ }
+ tp = tuple_val(BIF_ARG_2);
+ if (arityval(*tp) != 2) {
+ goto badarg;
+ }
+ return erts_binary_part(BIF_P,BIF_ARG_1,tp[1], tp[2]);
+ badarg:
+ BIF_ERROR(BIF_P,BADARG);
+}
+
+
/*
* The following code is used when a guard that may build on the
* heap is called directly. They must not use HAlloc(), but must
@@ -630,3 +654,16 @@ gc_double_to_integer(Process* p, double x, Eterm* reg, Uint live)
}
return res;
}
+
+/********************************************************************************
+ * binary_part guards. The actual implementation is in erl_bif_binary.c
+ ********************************************************************************/
+Eterm erts_gc_binary_part_3(Process* p, Eterm* reg, Uint live)
+{
+ return erts_gc_binary_part(p,reg,live,0);
+}
+
+Eterm erts_gc_binary_part_2(Process* p, Eterm* reg, Uint live)
+{
+ return erts_gc_binary_part(p,reg,live,1);
+}
diff --git a/erts/emulator/beam/erl_bif_info.c b/erts/emulator/beam/erl_bif_info.c
index 18cb09d8cd..70d0e91a2c 100644
--- a/erts/emulator/beam/erl_bif_info.c
+++ b/erts/emulator/beam/erl_bif_info.c
@@ -1140,9 +1140,9 @@ process_info_aux(Process *BIF_P,
}
else {
/* Make our copy of the message */
- ASSERT(size_object(msg) == hfp->size);
+ ASSERT(size_object(msg) == hfp->used_size);
msg = copy_struct(msg,
- hfp->size,
+ hfp->used_size,
&hp,
&MSO(BIF_P));
}
@@ -2715,7 +2715,7 @@ BIF_RETTYPE port_info_2(BIF_ALIST_2)
erts_doforall_links(prt->nlinks, &one_link_size, &size);
for (bp = prt->bp; bp; bp = bp->next)
- size += sizeof(ErlHeapFragment) + (bp->size - 1)*sizeof(Eterm);
+ size += sizeof(ErlHeapFragment) + (bp->alloc_size - 1)*sizeof(Eterm);
if (prt->linebuf)
size += sizeof(LineBuf) + prt->linebuf->ovsiz;
@@ -3567,6 +3567,17 @@ BIF_RETTYPE erts_debug_set_internal_state_2(BIF_ALIST_2)
}
}
}
+ else if (ERTS_IS_ATOM_STR("binary_loop_limit", BIF_ARG_1)) {
+ /* Used by binary_module_SUITE (stdlib) */
+ Uint max_loops;
+ if (is_atom(BIF_ARG_2) && ERTS_IS_ATOM_STR("default", BIF_ARG_2)) {
+ max_loops = erts_binary_set_loop_limit(-1);
+ BIF_RET(make_small(max_loops));
+ } else if (term_to_Uint(BIF_ARG_2, &max_loops) != 0) {
+ max_loops = erts_binary_set_loop_limit(max_loops);
+ BIF_RET(make_small(max_loops));
+ }
+ }
else if (ERTS_IS_ATOM_STR("re_loop_limit", BIF_ARG_1)) {
/* Used by re_SUITE (stdlib) */
Uint max_loops;
diff --git a/erts/emulator/beam/erl_bif_port.c b/erts/emulator/beam/erl_bif_port.c
index 9b56ddd4f8..378c5e73fd 100644
--- a/erts/emulator/beam/erl_bif_port.c
+++ b/erts/emulator/beam/erl_bif_port.c
@@ -579,8 +579,8 @@ BIF_RETTYPE port_get_data_1(BIF_ALIST_1)
if (prt->bp == NULL) { /* MUST be CONST! */
res = prt->data;
} else {
- Eterm* hp = HAlloc(BIF_P, prt->bp->size);
- res = copy_struct(prt->data, prt->bp->size, &hp, &MSO(BIF_P));
+ Eterm* hp = HAlloc(BIF_P, prt->bp->used_size);
+ res = copy_struct(prt->data, prt->bp->used_size, &hp, &MSO(BIF_P));
}
erts_smp_port_unlock(prt);
BIF_RET(res);
diff --git a/erts/emulator/beam/erl_bif_timer.c b/erts/emulator/beam/erl_bif_timer.c
index eb40c75110..4ae2f6ebf4 100644
--- a/erts/emulator/beam/erl_bif_timer.c
+++ b/erts/emulator/beam/erl_bif_timer.c
@@ -357,7 +357,7 @@ bif_timer_timeout(ErtsBifTimer* btm)
rp,
&rp_locks);
} else {
- Eterm old_size = bp->size;
+ Eterm old_size = bp->used_size;
bp = erts_resize_message_buffer(bp, old_size + wrap_size,
&message, 1);
hp = &bp->mem[0] + old_size;
diff --git a/erts/emulator/beam/erl_binary.h b/erts/emulator/beam/erl_binary.h
index 5b0b3bcec2..a569fe2e85 100644
--- a/erts/emulator/beam/erl_binary.h
+++ b/erts/emulator/beam/erl_binary.h
@@ -21,6 +21,7 @@
#define __ERL_BINARY_H
#include "erl_threads.h"
+#include "bif.h"
/*
* Maximum number of bytes to place in a heap binary.
@@ -150,7 +151,16 @@ do { \
void erts_init_binary(void);
-byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, unsigned extra);
+byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, ErtsAlcType_t, unsigned extra);
+
+/*
+ * Common implementation for erlang:list_to_binary/1 and binary:list_to_bin/1
+ */
+
+BIF_RETTYPE erts_list_to_binary_bif(Process *p, Eterm arg);
+BIF_RETTYPE erts_gc_binary_part(Process *p, Eterm *reg, Eterm live, int range_is_tuple);
+BIF_RETTYPE erts_binary_part(Process *p, Eterm binary, Eterm epos, Eterm elen);
+
#if defined(__i386__) || !defined(__GNUC__)
/*
@@ -168,6 +178,7 @@ byte* erts_get_aligned_binary_bytes_extra(Eterm, byte**, unsigned extra);
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 void erts_free_aligned_binary_bytes_extra(byte* buf, ErtsAlcType_t);
ERTS_GLB_INLINE Binary *erts_bin_drv_alloc_fnf(Uint size);
ERTS_GLB_INLINE Binary *erts_bin_drv_alloc(Uint size);
ERTS_GLB_INLINE Binary *erts_bin_nrml_alloc(Uint size);
@@ -184,17 +195,23 @@ ERTS_GLB_INLINE Binary *erts_create_magic_binary(Uint size,
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);
+ return erts_get_aligned_binary_bytes_extra(bin, base_ptr, ERTS_ALC_T_TMP, 0);
}
ERTS_GLB_INLINE void
-erts_free_aligned_binary_bytes(byte* buf)
+erts_free_aligned_binary_bytes_extra(byte* buf, ErtsAlcType_t allocator)
{
if (buf) {
- erts_free(ERTS_ALC_T_TMP, (void *) buf);
+ erts_free(allocator, (void *) buf);
}
}
+ERTS_GLB_INLINE void
+erts_free_aligned_binary_bytes(byte* buf)
+{
+ erts_free_aligned_binary_bytes_extra(buf,ERTS_ALC_T_TMP);
+}
+
/* 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?
diff --git a/erts/emulator/beam/erl_db_util.c b/erts/emulator/beam/erl_db_util.c
index fd7de98ac9..93a47eb76f 100644
--- a/erts/emulator/beam/erl_db_util.c
+++ b/erts/emulator/beam/erl_db_util.c
@@ -1547,10 +1547,9 @@ restart:
*/
context.save = NULL;
error: /* Here is were we land when compilation failed. */
- while (context.save != NULL) {
- ErlHeapFragment *ll = context.save->next;
+ if (context.save != NULL) {
free_message_buffer(context.save);
- context.save = ll;
+ context.save = NULL;
}
DMC_FREE(stack);
DMC_FREE(text);
@@ -1567,15 +1566,11 @@ error: /* Here is were we land when compilation failed. */
void erts_db_match_prog_destructor(Binary *bprog)
{
MatchProg *prog;
- ErlHeapFragment *tmp, *ll;
if (bprog == NULL)
return;
prog = Binary2MatchProg(bprog);
- tmp = prog->term_save;
- while (tmp != NULL) {
- ll = tmp->next;
- free_message_buffer(tmp);
- tmp = ll;
+ if (prog->term_save != NULL) {
+ free_message_buffer(prog->term_save);
}
if (prog->saved_program_buf != NULL)
free_message_buffer(prog->saved_program_buf);
@@ -4125,7 +4120,7 @@ static int match_compact(ErlHeapFragment *expr, DMCErrInfo *err_info)
DMC_INIT_STACK(heap);
p = expr->mem;
- i = expr->size;
+ i = expr->used_size;
while (i--) {
if (is_thing(*p)) {
a = thing_arityval(*p);
@@ -4154,7 +4149,7 @@ static int match_compact(ErlHeapFragment *expr, DMCErrInfo *err_info)
}
p = expr->mem;
- i = expr->size;
+ i = expr->used_size;
while (i--) {
if (is_thing(*p)) {
a = thing_arityval(*p);
diff --git a/erts/emulator/beam/erl_debug.c b/erts/emulator/beam/erl_debug.c
index 58d3f92f56..d7d6fcf0a2 100644
--- a/erts/emulator/beam/erl_debug.c
+++ b/erts/emulator/beam/erl_debug.c
@@ -261,7 +261,7 @@ static int verify_eterm(Process *p,Eterm element)
return 1;
for (mbuf = p->mbuf; mbuf; mbuf = mbuf->next) {
- if (WITHIN(ptr, &mbuf->mem[0], &mbuf->mem[0] + mbuf->size)) {
+ if (WITHIN(ptr, &mbuf->mem[0], &mbuf->mem[0] + mbuf->used_size)) {
return 1;
}
}
@@ -308,7 +308,7 @@ void erts_check_stack(Process *p)
if (IN_HEAP(p, ptr))
continue;
for (mbuf = p->mbuf; mbuf; mbuf = mbuf->next)
- if (WITHIN(ptr, &mbuf->mem[0], &mbuf->mem[0] + mbuf->size)) {
+ if (WITHIN(ptr, &mbuf->mem[0], &mbuf->mem[0] + mbuf->used_size)) {
in_mbuf = 1;
break;
}
@@ -746,7 +746,7 @@ static void print_process_memory(Process *p)
PTR_SIZE, "heap fragments",
dashes, dashes, dashes, dashes);
while (bp) {
- print_untagged_memory(bp->mem,bp->mem + bp->size);
+ print_untagged_memory(bp->mem,bp->mem + bp->used_size);
bp = bp->next;
}
}
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 9ed566e66e..a19e090f1e 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -667,7 +667,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, Uint lit_size)
case TAG_PRIMARY_BOXED:
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*g_ptr++ = val;
} else if (in_area(ptr, area, area_size)) {
@@ -679,7 +679,7 @@ erts_garbage_collect_literals(Process* p, Eterm* literals, Uint lit_size)
case TAG_PRIMARY_LIST:
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) { /* Moved */
+ if (IS_MOVED_CONS(val)) { /* Moved */
*g_ptr++ = ptr[1];
} else if (in_area(ptr, area, area_size)) {
MOVE_CONS(ptr,val,old_htop,g_ptr++);
@@ -913,7 +913,7 @@ do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*g_ptr++ = val;
} else if (in_area(ptr, heap, mature_size)) {
@@ -929,7 +929,7 @@ do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
case TAG_PRIMARY_LIST: {
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) { /* Moved */
+ if (IS_MOVED_CONS(val)) { /* Moved */
*g_ptr++ = ptr[1];
} else if (in_area(ptr, heap, mature_size)) {
MOVE_CONS(ptr,val,old_htop,g_ptr++);
@@ -972,7 +972,7 @@ do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*n_hp++ = val;
} else if (in_area(ptr, heap, mature_size)) {
@@ -987,7 +987,7 @@ do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
case TAG_PRIMARY_LIST: {
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
*n_hp++ = ptr[1];
} else if (in_area(ptr, heap, mature_size)) {
MOVE_CONS(ptr,val,old_htop,n_hp++);
@@ -1008,7 +1008,7 @@ do_minor(Process *p, int new_sz, Eterm* objv, int nobj)
Eterm* origptr = &(mb->orig);
ptr = boxed_val(*origptr);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
*origptr = val;
mb->base = binary_bytes(val);
} else if (in_area(ptr, heap, mature_size)) {
@@ -1161,7 +1161,7 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*g_ptr++ = val;
} else if (in_area(ptr, src, src_size) || in_area(ptr, oh, oh_size)) {
@@ -1175,7 +1175,7 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
case TAG_PRIMARY_LIST: {
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
*g_ptr++ = ptr[1];
} else if (in_area(ptr, src, src_size) || in_area(ptr, oh, oh_size)) {
MOVE_CONS(ptr,val,n_htop,g_ptr++);
@@ -1216,7 +1216,7 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*n_hp++ = val;
} else if (in_area(ptr, src, src_size) || in_area(ptr, oh, oh_size)) {
@@ -1229,7 +1229,7 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
case TAG_PRIMARY_LIST: {
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
*n_hp++ = ptr[1];
} else if (in_area(ptr, src, src_size) || in_area(ptr, oh, oh_size)) {
MOVE_CONS(ptr,val,n_htop,n_hp++);
@@ -1249,7 +1249,7 @@ major_collection(Process* p, int need, Eterm* objv, int nobj, Uint *recl)
origptr = &(mb->orig);
ptr = boxed_val(*origptr);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
*origptr = val;
mb->base = binary_bytes(*origptr);
} else if (in_area(ptr, src, src_size) ||
@@ -1392,17 +1392,12 @@ combined_message_size(Process* p)
static void
remove_message_buffers(Process* p)
{
- ErlHeapFragment* bp = MBUF(p);
-
- MBUF(p) = NULL;
- MBUF_SIZE(p) = 0;
- while (bp != NULL) {
- ErlHeapFragment* next_bp = bp->next;
- free_message_buffer(bp);
- bp = next_bp;
- }
+ if (MBUF(p) != NULL) {
+ free_message_buffer(MBUF(p));
+ MBUF(p) = NULL;
+ }
+ MBUF_SIZE(p) = 0;
}
-
#ifdef HARDDEBUG
/*
@@ -1433,12 +1428,12 @@ disallow_heap_frag_ref(Process* p, Eterm* n_htop, Eterm* objv, int nobj)
case TAG_PRIMARY_BOXED: {
ptr = _unchecked_boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
objv++;
} else {
for (qb = mbuf; qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
+ if (in_area(ptr, qb->mem, qb->alloc_size*sizeof(Eterm))) {
abort();
}
}
@@ -1450,11 +1445,11 @@ disallow_heap_frag_ref(Process* p, Eterm* n_htop, Eterm* objv, int nobj)
case TAG_PRIMARY_LIST: {
ptr = _unchecked_list_val(gval);
val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
objv++;
} else {
for (qb = mbuf; qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
+ if (in_area(ptr, qb->mem, qb->alloc_size*sizeof(Eterm))) {
abort();
}
}
@@ -1499,7 +1494,7 @@ disallow_heap_frag_ref_in_heap(Process* p)
ptr = _unchecked_boxed_val(val);
if (!in_area(ptr, heap, heap_size)) {
for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
+ if (in_area(ptr, qb->mem, qb->alloc_size*sizeof(Eterm))) {
abort();
}
}
@@ -1509,7 +1504,7 @@ disallow_heap_frag_ref_in_heap(Process* p)
ptr = _unchecked_list_val(val);
if (!in_area(ptr, heap, heap_size)) {
for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
+ if (in_area(ptr, qb->mem, qb->alloc_size*sizeof(Eterm))) {
abort();
}
}
@@ -1557,7 +1552,7 @@ disallow_heap_frag_ref_in_old_heap(Process* p)
abort();
}
for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
+ if (in_area(ptr, qb->mem, qb->alloc_size*sizeof(Eterm))) {
abort();
}
}
@@ -1570,7 +1565,7 @@ disallow_heap_frag_ref_in_old_heap(Process* p)
abort();
}
for (qb = MBUF(p); qb != NULL; qb = qb->next) {
- if (in_area(ptr, qb->mem, qb->size*sizeof(Eterm))) {
+ if (in_area(ptr, qb->mem, qb->alloc_size*sizeof(Eterm))) {
abort();
}
}
@@ -1610,7 +1605,7 @@ sweep_rootset(Rootset* rootset, Eterm* htop, char* src, Uint src_size)
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*g_ptr++ = val;
} else if (in_area(ptr, src, src_size)) {
@@ -1623,7 +1618,7 @@ sweep_rootset(Rootset* rootset, Eterm* htop, char* src, Uint src_size)
case TAG_PRIMARY_LIST: {
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) { /* Moved */
+ if (IS_MOVED_CONS(val)) {
*g_ptr++ = ptr[1];
} else if (in_area(ptr, src, src_size)) {
MOVE_CONS(ptr,val,htop,g_ptr++);
@@ -1657,7 +1652,7 @@ sweep_one_area(Eterm* n_hp, Eterm* n_htop, char* src, Uint src_size)
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*n_hp++ = val;
} else if (in_area(ptr, src, src_size)) {
@@ -1670,7 +1665,7 @@ sweep_one_area(Eterm* n_hp, Eterm* n_htop, char* src, Uint src_size)
case TAG_PRIMARY_LIST: {
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
*n_hp++ = ptr[1];
} else if (in_area(ptr, src, src_size)) {
MOVE_CONS(ptr,val,n_htop,n_hp++);
@@ -1690,7 +1685,7 @@ sweep_one_area(Eterm* n_hp, Eterm* n_htop, char* src, Uint src_size)
origptr = &(mb->orig);
ptr = boxed_val(*origptr);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
*origptr = val;
mb->base = binary_bytes(*origptr);
} else if (in_area(ptr, src, src_size)) {
@@ -1722,7 +1717,7 @@ sweep_one_heap(Eterm* heap_ptr, Eterm* heap_end, Eterm* htop, char* src, Uint sr
case TAG_PRIMARY_BOXED: {
ptr = boxed_val(gval);
val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*heap_ptr++ = val;
} else if (in_area(ptr, src, src_size)) {
@@ -1735,7 +1730,7 @@ sweep_one_heap(Eterm* heap_ptr, Eterm* heap_end, Eterm* htop, char* src, Uint sr
case TAG_PRIMARY_LIST: {
ptr = list_val(gval);
val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
*heap_ptr++ = ptr[1];
} else if (in_area(ptr, src, src_size)) {
MOVE_CONS(ptr,val,htop,heap_ptr++);
@@ -1830,28 +1825,6 @@ collect_heap_frags(Process* p, Eterm* n_hstart, Eterm* n_htop,
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)
{
@@ -2090,7 +2063,7 @@ sweep_proc_externals(Process *p, int fullsweep)
while (ptr) {
Eterm* ppt = (Eterm *) ptr;
- if (IS_MOVED(*ppt)) { /* Object is alive */
+ if (IS_MOVED_BOXED(*ppt)) { /* Object is alive */
ExternalThing* ro = external_thing_ptr(*ppt);
*prev = ro; /* Patch to moved pos */
@@ -2130,7 +2103,7 @@ sweep_proc_funs(Process *p, int fullsweep)
while (ptr) {
Eterm* ppt = (Eterm *) ptr;
- if (IS_MOVED(*ppt)) { /* Object is alive */
+ if (IS_MOVED_BOXED(*ppt)) { /* Object is alive */
ErlFunThing* ro = (ErlFunThing *) fun_val(*ppt);
*prev = ro; /* Patch to moved pos */
@@ -2244,7 +2217,7 @@ sweep_proc_bins(Process *p, int fullsweep)
while (ptr) {
Eterm* ppt = (Eterm *) ptr;
- if (IS_MOVED(*ppt)) { /* Object is alive */
+ if (IS_MOVED_BOXED(*ppt)) { /* Object is alive */
bin_vheap += ptr->size / sizeof(Eterm);
ptr = (ProcBin*) binary_val(*ppt);
link_live_proc_bin(&shrink,
@@ -2542,7 +2515,7 @@ within2(Eterm *ptr, Process *p, Eterm *real_htop)
return 1;
}
while (bp != NULL) {
- if (bp->mem <= ptr && ptr < bp->mem + bp->size) {
+ if (bp->mem <= ptr && ptr < bp->mem + bp->used_size) {
return 1;
}
bp = bp->next;
@@ -2556,7 +2529,7 @@ within2(Eterm *ptr, Process *p, Eterm *real_htop)
hfp = erts_dist_ext_trailer(mp->data.dist_ext);
else
hfp = NULL;
- if (hfp && hfp->mem <= ptr && ptr < hfp->mem + hfp->size)
+ if (hfp && hfp->mem <= ptr && ptr < hfp->mem + hfp->used_size)
return 1;
}
mp = mp->next;
diff --git a/erts/emulator/beam/erl_gc.h b/erts/emulator/beam/erl_gc.h
index af55b6363f..807ef8ae8d 100644
--- a/erts/emulator/beam/erl_gc.h
+++ b/erts/emulator/beam/erl_gc.h
@@ -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%
*/
@@ -22,11 +22,12 @@
/* GC declarations shared by beam/erl_gc.c and hipe/hipe_gc.c */
-#ifdef DEBUG
+#if defined(DEBUG) && !ERTS_GLB_INLINE_INCL_FUNC_DEF
# define HARDDEBUG 1
#endif
-#define IS_MOVED(x) (!is_header((x)))
+#define IS_MOVED_BOXED(x) (!is_header((x)))
+#define IS_MOVED_CONS(x) (is_non_value((x)))
#define MOVE_CONS(PTR,CAR,HTOP,ORIG) \
do { \
@@ -69,4 +70,28 @@ extern Uint erts_test_long_gc_sleep;
int within(Eterm *ptr, Process *p);
#endif
+ERTS_GLB_INLINE Eterm follow_moved(Eterm term);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+ERTS_GLB_INLINE 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_BOXED(*ptr)) term = *ptr;
+ break;
+ case TAG_PRIMARY_LIST:
+ ptr = list_val(term);
+ if (IS_MOVED_CONS(ptr[0])) term = ptr[1];
+ break;
+ default:
+ ASSERT(!"strange tag in follow_moved");
+ }
+ return term;
+}
+#endif
+
#endif /* __ERL_GC_H__ */
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index e63ec8a3cc..2ee802cf3e 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -281,6 +281,7 @@ erl_init(void)
init_load();
erts_init_bif();
erts_init_bif_chksum();
+ erts_init_bif_binary();
erts_init_bif_re();
erts_init_unicode(); /* after RE to get access to PCRE unicode */
erts_delay_trap = erts_export_put(am_erlang, am_delay_trap, 2);
@@ -335,59 +336,6 @@ init_shared_memory(int argc, char **argv)
#endif
}
-
-/*
- * Create the very first process.
- */
-
-void
-erts_first_process(Eterm modname, void* code, unsigned size, int argc, char** argv)
-{
- int i;
- Eterm args;
- Eterm pid;
- Eterm* hp;
- Process parent;
- Process* p;
- ErlSpawnOpts so;
-
- if (erts_find_function(modname, am_start, 1) == NULL) {
- char sbuf[256];
- Atom* ap;
-
- ap = atom_tab(atom_val(modname));
- memcpy(sbuf, ap->name, ap->len);
- sbuf[ap->len] = '\0';
- erl_exit(5, "No function %s:start/1\n", sbuf);
- }
-
- /*
- * We need a dummy parent process to be able to call erl_create_process().
- */
- erts_init_empty_process(&parent);
- hp = HAlloc(&parent, argc*2 + 4);
- args = NIL;
- for (i = argc-1; i >= 0; i--) {
- int len = sys_strlen(argv[i]);
- args = CONS(hp, new_binary(&parent, (byte*)argv[i], len), args);
- hp += 2;
- }
- args = CONS(hp, new_binary(&parent, code, size), args);
- hp += 2;
- args = CONS(hp, args, NIL);
-
- so.flags = 0;
- pid = erl_create_process(&parent, modname, am_start, args, &so);
- p = process_tab[internal_pid_index(pid)];
- p->group_leader = pid;
-
- erts_cleanup_empty_process(&parent);
-}
-
-/*
- * XXX Old way of starting. Hopefully soon obsolete.
- */
-
static void
erl_first_process_otp(char* modname, void* code, unsigned size, int argc, char** argv)
{
diff --git a/erts/emulator/beam/erl_message.c b/erts/emulator/beam/erl_message.c
index a056fce0c5..b63f3df7df 100644
--- a/erts/emulator/beam/erl_message.c
+++ b/erts/emulator/beam/erl_message.c
@@ -42,6 +42,15 @@ ERTS_SCHED_PREF_QUICK_ALLOC_IMPL(message,
#undef HARD_DEBUG
#endif
+
+
+
+static ERTS_INLINE int in_heapfrag(const Eterm* ptr, const ErlHeapFragment *bp)
+{
+ return ((unsigned)(ptr - bp->mem) < bp->used_size);
+}
+
+
void
init_message(void)
{
@@ -81,9 +90,12 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
#endif
ErlHeapFragment* nbp;
+ /* ToDo: Make use of 'used_size' to avoid realloc
+ when shrinking just a few words */
+
#ifdef DEBUG
{
- Uint off_sz = size < bp->size ? size : bp->size;
+ Uint off_sz = size < bp->used_size ? size : bp->used_size;
for (i = 0; i < brefs_size; i++) {
Eterm *ptr;
if (is_immed(brefs[i]))
@@ -95,12 +107,12 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
}
#endif
- if (size == bp->size)
+ if (size == bp->used_size)
return bp;
#ifdef HARD_DEBUG
dbg_brefs = erts_alloc(ERTS_ALC_T_UNDEF, sizeof(Eterm *)*brefs_size);
- dbg_bp = new_message_buffer(bp->size);
+ dbg_bp = new_message_buffer(bp->used_size);
dbg_hp = dbg_bp->mem;
dbg_tot_size = 0;
for (i = 0; i < brefs_size; i++) {
@@ -109,15 +121,15 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
dbg_brefs[i] = copy_struct(brefs[i], dbg_size, &dbg_hp,
&dbg_bp->off_heap);
}
- ASSERT(dbg_tot_size == (size < bp->size ? size : bp->size));
+ ASSERT(dbg_tot_size == (size < bp->used_size ? size : bp->used_size));
#endif
nbp = (ErlHeapFragment*) ERTS_HEAP_REALLOC(ERTS_ALC_T_HEAP_FRAG,
(void *) bp,
- ERTS_HEAP_FRAG_SIZE(bp->size),
+ ERTS_HEAP_FRAG_SIZE(bp->alloc_size),
ERTS_HEAP_FRAG_SIZE(size));
if (bp != nbp) {
- Uint off_sz = size < nbp->size ? size : nbp->size;
+ Uint off_sz = size < nbp->used_size ? size : nbp->used_size;
Eterm *sp = &bp->mem[0];
Eterm *ep = sp + off_sz;
Sint offs = &nbp->mem[0] - sp;
@@ -135,7 +147,7 @@ erts_resize_message_buffer(ErlHeapFragment *bp, Uint size,
}
#endif
}
- nbp->size = size;
+ nbp->alloc_size = size;
nbp->used_size = size;
#ifdef HARD_DEBUG
@@ -168,10 +180,15 @@ erts_cleanup_offheap(ErlOffHeap *offheap)
void
free_message_buffer(ErlHeapFragment* bp)
{
- erts_cleanup_offheap(&bp->off_heap);
- ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG,
- (void *) bp,
- ERTS_HEAP_FRAG_SIZE(bp->size));
+ ASSERT(bp != NULL);
+ do {
+ ErlHeapFragment* next_bp = bp->next;
+
+ erts_cleanup_offheap(&bp->off_heap);
+ ERTS_HEAP_FREE(ERTS_ALC_T_HEAP_FRAG, (void *) bp,
+ ERTS_HEAP_FRAG_SIZE(bp->size));
+ bp = next_bp;
+ }while (bp != NULL);
}
static ERTS_INLINE void
@@ -181,7 +198,7 @@ link_mbuf_to_proc(Process *proc, ErlHeapFragment *bp)
/* Link the message buffer */
bp->next = MBUF(proc);
MBUF(proc) = bp;
- MBUF_SIZE(proc) += bp->size;
+ MBUF_SIZE(proc) += bp->used_size;
FLAGS(proc) |= F_FORCE_GC;
/* Move any binaries into the process */
@@ -242,7 +259,7 @@ erts_msg_distext2heap(Process *pp,
goto decode_error;
if (is_not_nil(*tokenp)) {
ErlHeapFragment *heap_frag = erts_dist_ext_trailer(dist_extp);
- tok_sz = heap_frag->size;
+ tok_sz = heap_frag->used_size;
sz += tok_sz;
}
if (pp)
@@ -283,12 +300,13 @@ erts_msg_distext2heap(Process *pp,
erts_cleanup_offheap(&heap_frag->off_heap);
}
erts_free_dist_ext_copy(dist_extp);
- if (*bpp)
+ if (*bpp) {
free_message_buffer(*bpp);
+ *bpp = NULL;
+ }
else if (hp) {
HRelease(pp, hp_end, hp);
}
- *bpp = NULL;
return THE_NON_VALUE;
}
@@ -436,11 +454,10 @@ erts_queue_message(Process* receiver,
ERL_MESSAGE_TERM(mp) = message;
ERL_MESSAGE_TOKEN(mp) = seq_trace_token;
mp->next = NULL;
+ mp->data.heap_frag = bp;
#ifdef ERTS_SMP
if (*receiver_locks & ERTS_PROC_LOCK_MAIN) {
- mp->data.heap_frag = bp;
-
/*
* We move 'in queue' to 'private queue' and place
* message at the end of 'private queue' in order
@@ -453,11 +470,9 @@ erts_queue_message(Process* receiver,
LINK_MESSAGE_PRIVQ(receiver, mp);
}
else {
- mp->data.heap_frag = bp;
LINK_MESSAGE(receiver, mp);
}
#else
- mp->data.heap_frag = bp;
LINK_MESSAGE(receiver, mp);
#endif
@@ -530,32 +545,27 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
#ifdef HARD_DEBUG
dbg_term_sz = size_object(term);
dbg_token_sz = size_object(token);
- ASSERT(bp->size == dbg_term_sz + dbg_token_sz);
-
- dbg_bp = new_message_buffer(bp->size);
+ /*ASSERT(dbg_term_sz + dbg_token_sz == erts_msg_used_frag_sz(msg));
+ Copied size may be smaller due to removed SubBins's or garbage.
+ Copied size may be larger due to duplicated shared terms.
+ */
+ dbg_bp = new_message_buffer(dbg_term_sz + dbg_token_sz);
dbg_hp = dbg_bp->mem;
dbg_term = copy_struct(term, dbg_term_sz, &dbg_hp, &dbg_bp->off_heap);
dbg_token = copy_struct(token, dbg_token_sz, &dbg_hp, &dbg_bp->off_heap);
dbg_thp_start = *hpp;
#endif
- ASSERT(bp);
- msg->data.attached = NULL;
+ if (bp->next != NULL) {
+ move_multi_frags(hpp, off_heap, bp, msg->m, 2);
+ goto copy_done;
+ }
off_heap->overhead += bp->off_heap.overhead;
- sz = bp->size;
+ sz = bp->used_size;
-#ifdef DEBUG
- if (is_not_immed(term)) {
- ASSERT(bp->mem <= ptr_val(term));
- ASSERT(bp->mem + bp->size > ptr_val(term));
- }
-
- if (is_not_immed(token)) {
- ASSERT(bp->mem <= ptr_val(token));
- ASSERT(bp->mem + bp->size > ptr_val(token));
- }
-#endif
+ ASSERT(is_immed(term) || in_heapfrag(ptr_val(term),bp));
+ ASSERT(is_immed(token) || in_heapfrag(ptr_val(token),bp));
fhp = bp->mem;
hp = *hpp;
@@ -574,8 +584,7 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
break;
case TAG_PRIMARY_LIST:
case TAG_PRIMARY_BOXED:
- ASSERT(bp->mem <= ptr_val(val));
- ASSERT(bp->mem + bp->size > ptr_val(val));
+ ASSERT(in_heapfrag(ptr_val(val), bp));
*hp++ = offset_ptr(val, offs);
break;
case TAG_PRIMARY_HEADER:
@@ -609,6 +618,7 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
cpy_sz = header_arity(val);
cpy_words:
+ ASSERT(sz >= cpy_sz);
sz -= cpy_sz;
while (cpy_sz >= 8) {
cpy_sz -= 8;
@@ -676,12 +686,11 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
}
}
- ASSERT(bp->size == hp - *hpp);
+ ASSERT(bp->used_size == hp - *hpp);
*hpp = hp;
if (is_not_immed(token)) {
- ASSERT(bp->mem <= ptr_val(token));
- ASSERT(bp->mem + bp->size > ptr_val(token));
+ ASSERT(in_heapfrag(ptr_val(token), bp));
ERL_MESSAGE_TOKEN(msg) = offset_ptr(token, offs);
#ifdef HARD_DEBUG
ASSERT(dbg_thp_start <= ptr_val(ERL_MESSAGE_TOKEN(msg)));
@@ -690,8 +699,7 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
}
if (is_not_immed(term)) {
- ASSERT(bp->mem <= ptr_val(term));
- ASSERT(bp->mem + bp->size > ptr_val(term));
+ ASSERT(in_heapfrag(ptr_val(term),bp));
ERL_MESSAGE_TERM(msg) = offset_ptr(term, offs);
#ifdef HARD_DEBUG
ASSERT(dbg_thp_start <= ptr_val(ERL_MESSAGE_TERM(msg)));
@@ -699,10 +707,12 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
#endif
}
+copy_done:
#ifdef HARD_DEBUG
{
int i, j;
+ ErlHeapFragment* frag;
{
ProcBin *mso = off_heap->mso;
i = j = 0;
@@ -710,10 +720,12 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
mso = mso->next;
i++;
}
- mso = bp->off_heap.mso;
- while (mso) {
- mso = mso->next;
- j++;
+ for (frag=bp; frag; frag=frag->next) {
+ mso = frag->off_heap.mso;
+ while (mso) {
+ mso = mso->next;
+ j++;
+ }
}
ASSERT(i == j);
}
@@ -724,10 +736,12 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
fun = fun->next;
i++;
}
- fun = bp->off_heap.funs;
- while (fun) {
- fun = fun->next;
- j++;
+ for (frag=bp; frag; frag=frag->next) {
+ fun = frag->off_heap.funs;
+ while (fun) {
+ fun = fun->next;
+ j++;
+ }
}
ASSERT(i == j);
}
@@ -738,10 +752,12 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
external = external->next;
i++;
}
- external = bp->off_heap.externals;
- while (external) {
- external = external->next;
- j++;
+ for (frag=bp; frag; frag=frag->next) {
+ external = frag->off_heap.externals;
+ while (external) {
+ external = external->next;
+ j++;
+ }
}
ASSERT(i == j);
}
@@ -755,6 +771,7 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
#endif
bp->off_heap.externals = NULL;
free_message_buffer(bp);
+ msg->data.heap_frag = NULL;
#ifdef HARD_DEBUG
ASSERT(eq(ERL_MESSAGE_TERM(msg), dbg_term));
@@ -764,6 +781,7 @@ erts_move_msg_mbuf_to_heap(Eterm** hpp, ErlOffHeap* off_heap, ErlMessage *msg)
}
+
Uint
erts_msg_attached_data_size_aux(ErlMessage *msg)
{
@@ -789,7 +807,7 @@ erts_msg_attached_data_size_aux(ErlMessage *msg)
if (is_not_nil(msg->m[1])) {
ErlHeapFragment *heap_frag;
heap_frag = erts_dist_ext_trailer(msg->data.dist_ext);
- sz += heap_frag->size;
+ sz += heap_frag->used_size;
}
return sz;
}
@@ -805,7 +823,7 @@ erts_move_msg_attached_data_to_heap(Eterm **hpp, ErlOffHeap *ohp, ErlMessage *ms
ErlHeapFragment *heap_frag;
heap_frag = erts_dist_ext_trailer(msg->data.dist_ext);
ERL_MESSAGE_TOKEN(msg) = copy_struct(ERL_MESSAGE_TOKEN(msg),
- heap_frag->size,
+ heap_frag->used_size,
hpp,
ohp);
erts_cleanup_offheap(&heap_frag->off_heap);
@@ -1062,3 +1080,4 @@ erts_deliver_exit_message(Eterm from, Process *to, ErtsProcLocks *to_locksp,
erts_queue_message(to, to_locksp, bp, save, NIL);
}
}
+
diff --git a/erts/emulator/beam/erl_message.h b/erts/emulator/beam/erl_message.h
index 459c6363aa..f478572ac2 100644
--- a/erts/emulator/beam/erl_message.h
+++ b/erts/emulator/beam/erl_message.h
@@ -49,7 +49,7 @@ typedef struct erl_heap_fragment ErlHeapFragment;
struct erl_heap_fragment {
ErlHeapFragment* next; /* Next heap fragment */
ErlOffHeap off_heap; /* Offset heap data. */
- unsigned size; /* Size in (half)words of mem */
+ unsigned alloc_size; /* Size in (half)words of mem */
unsigned used_size; /* With terms to be moved to heap by GC */
Eterm mem[1]; /* Data */
};
@@ -75,6 +75,13 @@ typedef struct {
ErlMessage** last; /* point to the last next pointer */
ErlMessage** save;
int len; /* queue length */
+
+ /*
+ * The following two fields are used by the recv_mark/1 and
+ * recv_set/1 instructions.
+ */
+ BeamInstr* mark; /* address to rec_loop/2 instruction */
+ ErlMessage** saved_last; /* saved last pointer */
} ErlMessageQueue;
#ifdef ERTS_SMP
@@ -137,6 +144,7 @@ do { \
(p)->msg.len--; \
if (__mp == NULL) \
(p)->msg.last = (p)->msg.save; \
+ (p)->msg.mark = 0; \
} while(0)
/* Reset message save point (after receive match) */
@@ -191,7 +199,7 @@ do { \
#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)->alloc_size = (DATA_WORDS); \
(HEAP_FRAG_P)->used_size = (DATA_WORDS); \
(HEAP_FRAG_P)->off_heap.mso = NULL; \
(HEAP_FRAG_P)->off_heap.funs = NULL; \
@@ -219,14 +227,25 @@ void erts_move_msg_attached_data_to_heap(Eterm **, ErlOffHeap *, ErlMessage *);
Eterm erts_msg_distext2heap(Process *, ErtsProcLocks *, ErlHeapFragment **,
Eterm *, ErtsDistExternal *);
+ERTS_GLB_INLINE Uint erts_msg_used_frag_sz(const ErlMessage *msg);
ERTS_GLB_INLINE Uint erts_msg_attached_data_size(ErlMessage *msg);
#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+ERTS_GLB_INLINE Uint erts_msg_used_frag_sz(const ErlMessage *msg)
+{
+ const ErlHeapFragment *bp;
+ Uint sz = 0;
+ for (bp = msg->data.heap_frag; bp!=NULL; bp=bp->next) {
+ sz += bp->used_size;
+ }
+ return sz;
+}
+
ERTS_GLB_INLINE Uint erts_msg_attached_data_size(ErlMessage *msg)
{
ASSERT(msg->data.attached);
if (is_value(ERL_MESSAGE_TERM(msg)))
- return msg->data.heap_frag->size;
+ return erts_msg_used_frag_sz(msg);
else if (msg->data.dist_ext->heap_size < 0)
return erts_msg_attached_data_size_aux(msg);
else {
@@ -234,7 +253,7 @@ ERTS_GLB_INLINE Uint erts_msg_attached_data_size(ErlMessage *msg)
if (is_not_nil(ERL_MESSAGE_TOKEN(msg))) {
ErlHeapFragment *heap_frag;
heap_frag = erts_dist_ext_trailer(msg->data.dist_ext);
- sz += heap_frag->size;
+ sz += heap_frag->used_size;
}
return sz;
}
diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c
index 2790020117..75de00d4c1 100644
--- a/erts/emulator/beam/erl_nif.c
+++ b/erts/emulator/beam/erl_nif.c
@@ -48,7 +48,7 @@ struct erl_module_nif {
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 */
+ Module* mod; /* Can be NULL if orphan with dtor-resources left */
};
#ifdef DEBUG
@@ -61,6 +61,10 @@ static void add_readonly_check(ErlNifEnv*, unsigned char* ptr, unsigned sz);
# define ADD_READONLY_CHECK(ENV,PTR,SIZE) ((void)0)
#endif
+#ifdef DEBUG
+static int is_offheap(const ErlOffHeap* off_heap);
+#endif
+
#define MIN_HEAP_FRAG_SZ 200
static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp);
@@ -84,7 +88,8 @@ static Eterm* alloc_heap_heavy(ErlNifEnv* env, unsigned need, Eterm* hp)
HEAP_TOP(env->proc) = env->hp;
}
else {
- HRelease(env->proc, env->hp_end, env->hp);
+ env->heap_frag->used_size = hp - env->heap_frag->mem;
+ ASSERT(env->heap_frag->used_size <= env->heap_frag->alloc_size);
}
frag_sz = need + MIN_HEAP_FRAG_SZ;
hp = erts_heap_alloc(env->proc, frag_sz);
@@ -143,8 +148,9 @@ void erts_post_nif(ErlNifEnv* env)
}
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);
+ ASSERT(env->hp_end - env->hp <= env->heap_frag->alloc_size);
+ env->heap_frag->used_size = env->hp - env->heap_frag->mem;
+ ASSERT(env->heap_frag->used_size <= env->heap_frag->alloc_size);
}
free_tmp_objs(env);
}
@@ -158,7 +164,7 @@ static void post_nif_noproc(ErlNifEnv* env)
/* Flush out our cached heap pointers to allow an ordinary HAlloc
*/
-static void enable_halloc(ErlNifEnv* env)
+static void flush_env(ErlNifEnv* env)
{
if (env->heap_frag == NULL) {
ASSERT(env->hp_end == HEAP_LIMIT(env->proc));
@@ -168,14 +174,15 @@ static void enable_halloc(ErlNifEnv* env)
}
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);
+ ASSERT(env->hp_end - env->hp <= env->heap_frag->alloc_size);
+ env->heap_frag->used_size = env->hp - env->heap_frag->mem;
+ ASSERT(env->heap_frag->used_size <= env->heap_frag->alloc_size);
}
}
-/* Restore cached heap pointers
+/* Restore cached heap pointers to allow alloc_heap again.
*/
-static void disable_halloc(ErlNifEnv* env)
+static void cache_env(ErlNifEnv* env)
{
if (env->heap_frag == NULL) {
ASSERT(env->hp_end == HEAP_LIMIT(env->proc));
@@ -185,34 +192,192 @@ static void disable_halloc(ErlNifEnv* env)
}
else {
ASSERT(env->hp_end != HEAP_LIMIT(env->proc));
- ASSERT(env->hp_end - env->hp <= env->heap_frag->size);
+ ASSERT(env->hp_end - env->hp <= env->heap_frag->alloc_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;
+ env->hp_end = env->heap_frag->mem + env->heap_frag->alloc_size;
}
}
-
void* enif_priv_data(ErlNifEnv* env)
{
return env->mod_nif->priv_data;
}
-void* enif_alloc(ErlNifEnv* env, size_t size)
+void* enif_alloc(size_t size)
{
return erts_alloc_fnf(ERTS_ALC_T_NIF, (Uint) size);
}
-void* enif_realloc(ErlNifEnv* env, void* ptr, size_t size)
+void* enif_realloc(void* ptr, size_t size)
{
return erts_realloc_fnf(ERTS_ALC_T_NIF, ptr, size);
}
-void enif_free(ErlNifEnv* env, void* ptr)
+void enif_free(void* ptr)
{
erts_free(ERTS_ALC_T_NIF, ptr);
}
+struct enif_msg_environment_t
+{
+ ErlNifEnv env;
+ Process phony_proc;
+};
+
+ErlNifEnv* enif_alloc_env(void)
+{
+ struct enif_msg_environment_t* msg_env =
+ erts_alloc_fnf(ERTS_ALC_T_NIF, sizeof(struct enif_msg_environment_t));
+ Eterm* phony_heap = (Eterm*) msg_env; /* dummy non-NULL ptr */
+
+ msg_env->env.hp = phony_heap;
+ msg_env->env.hp_end = phony_heap;
+ msg_env->env.heap_frag = NULL;
+ msg_env->env.mod_nif = NULL;
+ msg_env->env.tmp_obj_list = (struct enif_tmp_obj_t*) 1; /* invalid non-NULL */
+ msg_env->env.proc = &msg_env->phony_proc;
+ memset(&msg_env->phony_proc, 0, sizeof(Process));
+ HEAP_START(&msg_env->phony_proc) = phony_heap;
+ HEAP_TOP(&msg_env->phony_proc) = phony_heap;
+ HEAP_LIMIT(&msg_env->phony_proc) = phony_heap;
+ HEAP_END(&msg_env->phony_proc) = phony_heap;
+ MBUF(&msg_env->phony_proc) = NULL;
+ msg_env->phony_proc.id = ERTS_INVALID_PID;
+#ifdef FORCE_HEAP_FRAGS
+ msg_env->phony_proc.space_verified = 0;
+ msg_env->phony_proc.space_verified_from = NULL;
+#endif
+ return &msg_env->env;
+}
+void enif_free_env(ErlNifEnv* env)
+{
+ enif_clear_env(env);
+ erts_free(ERTS_ALC_T_NIF, env);
+}
+
+static ERTS_INLINE void clear_offheap(ErlOffHeap* oh)
+{
+ oh->mso = NULL;
+ oh->externals = NULL;
+ oh->funs = NULL;
+ oh->overhead = 0;
+}
+
+void enif_clear_env(ErlNifEnv* env)
+{
+ struct enif_msg_environment_t* menv = (struct enif_msg_environment_t*)env;
+ Process* p = &menv->phony_proc;
+ ASSERT(p == menv->env.proc);
+ ASSERT(p->id == ERTS_INVALID_PID);
+ ASSERT(MBUF(p) == menv->env.heap_frag);
+ if (MBUF(p) != NULL) {
+ erts_cleanup_offheap(&MSO(p));
+ clear_offheap(&MSO(p));
+ free_message_buffer(MBUF(p));
+ MBUF(p) = NULL;
+ menv->env.heap_frag = NULL;
+ }
+ ASSERT(HEAP_TOP(p) == HEAP_END(p));
+ menv->env.hp = menv->env.hp_end = HEAP_TOP(p);
+
+ ASSERT(!is_offheap(&MSO(p)));
+}
+int enif_send(ErlNifEnv* env, const ErlNifPid* to_pid,
+ ErlNifEnv* msg_env, ERL_NIF_TERM msg)
+{
+ struct enif_msg_environment_t* menv = (struct enif_msg_environment_t*)msg_env;
+ ErtsProcLocks rp_locks = 0;
+ Process* rp;
+ Process* c_p;
+ ErlHeapFragment* frags;
+#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
+ ErtsProcLocks rp_had_locks;
+#endif
+ Eterm receiver = to_pid->pid;
+ int flush_me = 0;
+
+ if (env != NULL) {
+ c_p = env->proc;
+ if (receiver == c_p->id) {
+ rp_locks = ERTS_PROC_LOCK_MAIN;
+ flush_me = 1;
+ }
+ }
+ else {
+#ifdef ERTS_SMP
+ c_p = NULL;
+#else
+ erl_exit(ERTS_ABORT_EXIT,"enif_send: env==NULL on non-SMP VM");
+#endif
+ }
+
+#if defined(ERTS_ENABLE_LOCK_CHECK) && defined(ERTS_SMP)
+ rp_had_locks = rp_locks;
+#endif
+ rp = erts_pid2proc_opt(c_p, ERTS_PROC_LOCK_MAIN,
+ receiver, rp_locks, ERTS_P2P_FLG_SMP_INC_REFC);
+ if (rp == NULL) {
+ ASSERT(env == NULL || receiver != c_p->id);
+ return 0;
+ }
+ flush_env(msg_env);
+ frags = menv->env.heap_frag;
+ ASSERT(frags == MBUF(&menv->phony_proc));
+ if (frags != NULL) {
+ /* Move all offheap's from phony proc to the first fragment.
+ Quick and dirty, but erts_move_msg_mbuf_to_heap doesn't care. */
+ ASSERT(!is_offheap(&frags->off_heap));
+ frags->off_heap = MSO(&menv->phony_proc);
+ clear_offheap(&MSO(&menv->phony_proc));
+ menv->env.heap_frag = NULL;
+ MBUF(&menv->phony_proc) = NULL;
+ }
+ ASSERT(!is_offheap(&MSO(&menv->phony_proc)));
+
+ if (flush_me) {
+ flush_env(env); /* Needed for ERTS_HOLE_CHECK */
+ }
+ erts_queue_message(rp, &rp_locks, frags, msg, am_undefined);
+ if (rp_locks) {
+ ERTS_SMP_LC_ASSERT(rp_locks == (rp_had_locks | (ERTS_PROC_LOCK_MSGQ |
+ ERTS_PROC_LOCK_STATUS)));
+ erts_smp_proc_unlock(rp, (ERTS_PROC_LOCK_MSGQ | ERTS_PROC_LOCK_STATUS));
+ }
+ erts_smp_proc_dec_refc(rp);
+ if (flush_me) {
+ cache_env(env);
+ }
+ return 1;
+}
+
+ERL_NIF_TERM enif_make_copy(ErlNifEnv* dst_env, ERL_NIF_TERM src_term)
+{
+ Uint sz;
+ Eterm* hp;
+ sz = size_object(src_term);
+ hp = alloc_heap(dst_env, sz);
+ return copy_struct(src_term, sz, &hp, &MSO(dst_env->proc));
+}
+
+
+#ifdef DEBUG
+static int is_offheap(const ErlOffHeap* oh)
+{
+ return oh->mso != NULL || oh->funs != NULL || oh->externals != NULL;
+}
+#endif
+
+ErlNifPid* enif_self(ErlNifEnv* caller_env, ErlNifPid* pid)
+{
+ pid->pid = caller_env->proc->id;
+ return pid;
+}
+int enif_get_local_pid(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifPid* pid)
+{
+ return is_internal_pid(term) ? (pid->pid=term, 1) : 0;
+}
+
int enif_is_atom(ErlNifEnv* env, ERL_NIF_TERM term)
{
return is_atom(term);
@@ -248,9 +413,19 @@ int enif_is_ref(ErlNifEnv* env, ERL_NIF_TERM term)
return is_ref(term);
}
+int enif_is_tuple(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_tuple(term);
+}
+
+int enif_is_list(ErlNifEnv* env, ERL_NIF_TERM term)
+{
+ return is_list(term) || is_nil(term);
+}
+
static void aligned_binary_dtor(struct enif_tmp_obj_t* obj)
{
- erts_free_aligned_binary_bytes((byte*)obj);
+ erts_free_aligned_binary_bytes_extra((byte*)obj,ERTS_ALC_T_TMP);
}
int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin)
@@ -260,7 +435,7 @@ int enif_inspect_binary(ErlNifEnv* env, Eterm bin_term, ErlNifBinary* bin)
byte* raw_ptr;
}u;
u.tmp = NULL;
- bin->data = erts_get_aligned_binary_bytes_extra(bin_term, &u.raw_ptr,
+ bin->data = erts_get_aligned_binary_bytes_extra(bin_term, &u.raw_ptr, ERTS_ALC_T_TMP,
sizeof(struct enif_tmp_obj_t));
if (bin->data == NULL) {
return 0;
@@ -314,7 +489,7 @@ int enif_inspect_iolist_as_binary(ErlNifEnv* env, Eterm term, ErlNifBinary* bin)
return 1;
}
-int enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin)
+int enif_alloc_binary(size_t size, ErlNifBinary* bin)
{
Binary* refbin;
@@ -333,7 +508,7 @@ int enif_alloc_binary(ErlNifEnv* env, unsigned size, ErlNifBinary* bin)
return 1;
}
-int enif_realloc_binary(ErlNifEnv* env, ErlNifBinary* bin, unsigned size)
+int enif_realloc_binary(ErlNifBinary* bin, size_t size)
{
if (bin->ref_bin != NULL) {
Binary* oldbin;
@@ -351,15 +526,15 @@ int enif_realloc_binary(ErlNifEnv* env, ErlNifBinary* bin, unsigned size)
}
else {
unsigned char* old_data = bin->data;
- unsigned cpy_sz = (size < bin->size ? size : bin->size);
- enif_alloc_binary(env, size, bin);
+ size_t cpy_sz = (size < bin->size ? size : bin->size);
+ enif_alloc_binary(size, bin);
sys_memcpy(bin->data, old_data, cpy_sz);
}
return 1;
}
-void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)
+void enif_release_binary(ErlNifBinary* bin)
{
if (bin->ref_bin != NULL) {
Binary* refbin = bin->ref_bin;
@@ -375,21 +550,21 @@ void enif_release_binary(ErlNifEnv* env, ErlNifBinary* bin)
#endif
}
-unsigned char* enif_make_new_binary(ErlNifEnv* env, unsigned size,
+unsigned char* enif_make_new_binary(ErlNifEnv* env, size_t size,
ERL_NIF_TERM* termp)
{
- enable_halloc(env);
+ flush_env(env);
*termp = new_binary(env->proc, NULL, size);
- disable_halloc(env);
+ cache_env(env);
return binary_bytes(*termp);
}
-int enif_is_identical(ErlNifEnv* env, Eterm lhs, Eterm rhs)
+int enif_is_identical(Eterm lhs, Eterm rhs)
{
return EQ(lhs,rhs);
}
-int enif_compare(ErlNifEnv* env, Eterm lhs, Eterm rhs)
+int enif_compare(Eterm lhs, Eterm rhs)
{
return cmp(lhs,rhs);
}
@@ -468,15 +643,15 @@ Eterm enif_make_binary(ErlNifEnv* env, ErlNifBinary* bin)
return bin_term;
}
else {
- enable_halloc(env);
+ flush_env(env);
bin->bin_term = new_binary(env->proc, bin->data, bin->size);
- disable_halloc(env);
+ cache_env(env);
return bin->bin_term;
}
}
Eterm enif_make_sub_binary(ErlNifEnv* env, ERL_NIF_TERM bin_term,
- unsigned pos, unsigned size)
+ size_t pos, size_t size)
{
ErlSubBin* sb;
Eterm orig;
@@ -506,9 +681,11 @@ Eterm enif_make_badarg(ErlNifEnv* env)
BIF_ERROR(env->proc, BADARG);
}
-int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len)
+int enif_get_atom(ErlNifEnv* env, Eterm atom, char* buf, unsigned len,
+ ErlNifCharEncoding encoding)
{
Atom* ap;
+ ASSERT(encoding == ERL_NIF_LATIN1);
if (is_not_atom(atom)) {
return 0;
}
@@ -556,10 +733,8 @@ int enif_get_long(ErlNifEnv* env, Eterm term, long* ip)
#if SIZEOF_LONG == ERTS_SIZEOF_ETERM
return term_to_Sint(term, ip);
#elif SIZEOF_INT == ERTS_SIZEOF_ETERM
- Uint u;
- term_to_Sint(term, u);
- *ip = (long) u;
- return 1;
+ Sint i;
+ return term_to_Sint(term, &i) ? (*ip = (long) i, 1) : 0;
#else
# error Unknown long word size
#endif
@@ -571,10 +746,7 @@ int enif_get_ulong(ErlNifEnv* env, Eterm term, unsigned long* ip)
return term_to_Uint(term, ip);
#elif SIZEOF_INT == ERTS_SIZEOF_ETERM
Uint u;
- int r;
- r = term_to_Uint(term, &u);
- *ip = (unsigned long) u;
- return r;
+ return term_to_Uint(term, &u) ? (*ip = (unsigned long) u, 1) : 0;
#else
# error Unknown long word size
#endif
@@ -591,6 +763,17 @@ int enif_get_double(ErlNifEnv* env, Eterm term, double* dp)
return 1;
}
+int enif_get_atom_length(ErlNifEnv* env, Eterm atom, unsigned* len,
+ ErlNifCharEncoding enc)
+{
+ Atom* ap;
+ ASSERT(enc == ERL_NIF_LATIN1);
+ if (is_not_atom(atom)) return 0;
+ ap = atom_tab(atom_val(atom));
+ *len = ap->len;
+ return 1;
+}
+
int enif_get_list_cell(ErlNifEnv* env, Eterm term, Eterm* head, Eterm* tail)
{
Eterm* val;
@@ -601,6 +784,13 @@ int enif_get_list_cell(ErlNifEnv* env, Eterm term, Eterm* head, Eterm* tail)
return 1;
}
+int enif_get_list_length(ErlNifEnv* env, Eterm term, unsigned* len)
+{
+ if (is_not_list(term) && is_not_nil(term)) return 0;
+ *len = list_length(term);
+ return 1;
+}
+
ERL_NIF_TERM enif_make_int(ErlNifEnv* env, int i)
{
#if SIZEOF_INT == ERTS_SIZEOF_ETERM
@@ -640,12 +830,25 @@ ERL_NIF_TERM enif_make_double(ErlNifEnv* env, double d)
ERL_NIF_TERM enif_make_atom(ErlNifEnv* env, const char* name)
{
- return am_atom_put(name, sys_strlen(name));
+ return enif_make_atom_len(env, name, sys_strlen(name));
+}
+
+ERL_NIF_TERM enif_make_atom_len(ErlNifEnv* env, const char* name, size_t len)
+{
+ return am_atom_put(name, len);
+}
+
+int enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom,
+ ErlNifCharEncoding enc)
+{
+ return enif_make_existing_atom_len(env, name, sys_strlen(name), atom, enc);
}
-int enif_make_existing_atom(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom)
+int enif_make_existing_atom_len(ErlNifEnv* env, const char* name, size_t len,
+ ERL_NIF_TERM* atom, ErlNifCharEncoding encoding)
{
- return erts_atom_get(name, sys_strlen(name), atom);
+ ASSERT(encoding == ERL_NIF_LATIN1);
+ return erts_atom_get(name, len, atom);
}
ERL_NIF_TERM enif_make_tuple(ErlNifEnv* env, unsigned cnt, ...)
@@ -724,11 +927,16 @@ ERL_NIF_TERM enif_make_list_from_array(ErlNifEnv* env, const ERL_NIF_TERM arr[],
ERL_NIF_TERM enif_make_string(ErlNifEnv* env, const char* string,
ErlNifCharEncoding encoding)
-{
- Sint n = sys_strlen(string);
- Eterm* hp = alloc_heap(env,n*2);
+{
+ return enif_make_string_len(env, string, sys_strlen(string), encoding);
+}
+
+ERL_NIF_TERM enif_make_string_len(ErlNifEnv* env, const char* string,
+ size_t len, ErlNifCharEncoding encoding)
+{
+ Eterm* hp = alloc_heap(env,len*2);
ASSERT(encoding == ERL_NIF_LATIN1);
- return erts_bld_string_n(&hp,NULL,string,n);
+ return erts_bld_string_n(&hp,NULL,string,len);
}
ERL_NIF_TERM enif_make_ref(ErlNifEnv* env)
@@ -799,7 +1007,8 @@ struct enif_resource_type_t
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];
+ Eterm module;
+ Eterm name;
};
/* dummy node in circular list */
@@ -817,14 +1026,14 @@ typedef struct enif_resource_t
#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)
+static ErlNifResourceType* find_resource_type(Eterm module, Eterm name)
{
ErlNifResourceType* type;
for (type = resource_type_list.next;
type != &resource_type_list;
type = type->next) {
- if (sys_strcmp(type->name, name) == 0) {
+ if (type->module == module && type->name == name) {
return type;
}
}
@@ -857,33 +1066,42 @@ static void steal_resource_type(ErlNifResourceType* type)
if (type->dtor != NULL
&& erts_refc_dectest(&lib->rt_dtor_cnt, 0) == 0
- && lib->is_orphan) {
+ && lib->mod == NULL) {
/* last type with destructor gone, close orphan lib */
close_lib(lib);
}
if (erts_refc_dectest(&lib->rt_cnt, 0) == 0
- && lib->is_orphan) {
+ && lib->mod == NULL) {
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)
+enif_open_resource_type(ErlNifEnv* env,
+ const char* module_str,
+ const char* name_str,
+ ErlNifResourceDtor* dtor,
+ ErlNifResourceFlags flags,
+ ErlNifResourceFlags* tried)
{
- ErlNifResourceType* type = find_resource_type(type_name);
- enum ErlNifResourceFlags op = flags;
+ ErlNifResourceType* type = NULL;
+ ErlNifResourceFlags op = flags;
+ Eterm module_am, name_am;
+
ASSERT(erts_smp_is_system_blocked(0));
+ ASSERT(module_str == NULL); /* for now... */
+ module_am = make_atom(env->mod_nif->mod->module);
+ name_am = enif_make_atom(env, name_str);
+
+ type = find_resource_type(module_am, name_am);
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));
+ sizeof(struct enif_resource_type_t));
type->dtor = dtor;
- sys_strcpy(type->name, type_name);
+ type->module = module_am;
+ type->name = name_am;
erts_refc_init(&type->refc, 1);
type->owner = env->mod_nif;
type->prev = &resource_type_list;
@@ -931,13 +1149,13 @@ static void nif_resource_dtor(Binary* bin)
if (erts_refc_dectest(&type->refc, 0) == 0) {
ASSERT(type->next == NULL);
ASSERT(type->owner != NULL);
- ASSERT(type->owner->is_orphan);
+ ASSERT(type->owner->mod == NULL);
steal_resource_type(type);
erts_free(ERTS_ALC_T_NIF, type);
}
}
-void* enif_alloc_resource(ErlNifEnv* env, ErlNifResourceType* type, unsigned size)
+void* enif_alloc_resource(ErlNifResourceType* type, size_t size)
{
Binary* bin = erts_create_magic_binary(SIZEOF_ErlNifResource(size), &nif_resource_dtor);
ErlNifResource* resource = ERTS_MAGIC_BIN_DATA(bin);
@@ -950,7 +1168,7 @@ void* enif_alloc_resource(ErlNifEnv* env, ErlNifResourceType* type, unsigned siz
return resource->data;
}
-void enif_release_resource(ErlNifEnv* env, void* obj)
+void enif_release_resource(void* obj)
{
ErlNifResource* resource = DATA_TO_RESOURCE(obj);
ErtsBinary* bin = ERTS_MAGIC_BIN_FROM_DATA(resource);
@@ -964,6 +1182,18 @@ void enif_release_resource(ErlNifEnv* env, void* obj)
}
}
+void enif_keep_resource(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_inc(&resource->nif_refc, 1);
+#endif
+ erts_refc_inc(&bin->binary.refc, 2);
+}
+
ERL_NIF_TERM enif_make_resource(ErlNifEnv* env, void* obj)
{
ErlNifResource* resource = DATA_TO_RESOURCE(obj);
@@ -972,15 +1202,30 @@ ERL_NIF_TERM enif_make_resource(ErlNifEnv* env, void* obj)
return erts_mk_magic_binary_term(&hp, &MSO(env->proc), &bin->binary);
}
+ERL_NIF_TERM enif_make_resource_binary(ErlNifEnv* env, void* obj,
+ const void* data, size_t size)
+{
+ Eterm bin = enif_make_resource(env, obj);
+ ProcBin* pb = (ProcBin*) binary_val(bin);
+ pb->bytes = (byte*) data;
+ pb->size = size;
+ return bin;
+}
+
int enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* type,
void** objp)
{
+ ProcBin* pb;
Binary* mbin;
ErlNifResource* resource;
if (!ERTS_TERM_IS_MAGIC_BINARY(term)) {
return 0;
}
- mbin = ((ProcBin*) binary_val(term))->val;
+ pb = (ProcBin*) binary_val(term);
+ /*if (pb->size != 0) {
+ return 0; / * Or should we allow "resource binaries" as handles? * /
+ }*/
+ mbin = pb->val;
resource = (ErlNifResource*) ERTS_MAGIC_BIN_DATA(mbin);
if (ERTS_MAGIC_BIN_DESTRUCTOR(mbin) != &nif_resource_dtor
|| resource->type != type) {
@@ -990,7 +1235,7 @@ int enif_get_resource(ErlNifEnv* env, ERL_NIF_TERM term, ErlNifResourceType* typ
return 1;
}
-unsigned enif_sizeof_resource(ErlNifEnv* env, void* obj)
+size_t enif_sizeof_resource(void* obj)
{
ErlNifResource* resource = DATA_TO_RESOURCE(obj);
Binary* bin = &ERTS_MAGIC_BIN_FROM_DATA(resource)->binary;
@@ -1220,7 +1465,7 @@ BIF_RETTYPE load_nif_2(BIF_ALIST_2)
lib->entry = entry;
erts_refc_init(&lib->rt_cnt, 0);
erts_refc_init(&lib->rt_dtor_cnt, 0);
- lib->is_orphan = 0;
+ lib->mod = mod;
env.mod_nif = lib;
if (mod->nif != NULL) { /* Reload */
int k;
@@ -1334,7 +1579,7 @@ erts_unload_nif(struct erl_module_nif* lib)
ErlNifResourceType* next;
ASSERT(erts_smp_is_system_blocked(0));
ASSERT(lib != NULL);
- ASSERT(!lib->is_orphan);
+ ASSERT(lib->mod != NULL);
for (rt = resource_type_list.next;
rt != &resource_type_list;
rt = next) {
@@ -1364,7 +1609,7 @@ erts_unload_nif(struct erl_module_nif* lib)
else {
ASSERT(erts_refc_read(&lib->rt_cnt, 1) > 0);
}
- lib->is_orphan = 1;
+ lib->mod = NULL; /* orphan lib */
}
void erl_nif_init()
@@ -1373,7 +1618,8 @@ void erl_nif_init()
resource_type_list.prev = &resource_type_list;
resource_type_list.dtor = NULL;
resource_type_list.owner = NULL;
- resource_type_list.name[0] = '\0';
+ resource_type_list.module = THE_NON_VALUE;
+ resource_type_list.name = THE_NON_VALUE;
}
#ifdef READONLY_CHECK
diff --git a/erts/emulator/beam/erl_nif.h b/erts/emulator/beam/erl_nif.h
index a345837569..936f03bce1 100644
--- a/erts/emulator/beam/erl_nif.h
+++ b/erts/emulator/beam/erl_nif.h
@@ -23,14 +23,16 @@
#ifndef __ERL_NIF_H__
#define __ERL_NIF_H__
+
#include "erl_drv_nif.h"
/* Version history:
** 0.1: R13B03
** 1.0: R13B04
+** 2.0: R14A
*/
-#define ERL_NIF_MAJOR_VERSION 1
-#define ERL_NIF_MINOR_VERSION 1
+#define ERL_NIF_MAJOR_VERSION 2
+#define ERL_NIF_MINOR_VERSION 0
#include <stdlib.h>
@@ -60,6 +62,10 @@
#endif
#include "erl_int_sizes_config.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#ifdef HALFWORD_HEAP_EMULATOR
typedef unsigned int ERL_NIF_TERM;
#else
@@ -93,7 +99,7 @@ typedef struct enif_entry_t
typedef struct
{
- unsigned size;
+ size_t size;
unsigned char* data;
/* Internals (avert your eyes) */
@@ -103,17 +109,22 @@ typedef struct
typedef struct enif_resource_type_t ErlNifResourceType;
typedef void ErlNifResourceDtor(ErlNifEnv*, void*);
-enum ErlNifResourceFlags
+typedef enum
{
ERL_NIF_RT_CREATE = 1,
ERL_NIF_RT_TAKEOVER = 2
-};
+}ErlNifResourceFlags;
typedef enum
{
ERL_NIF_LATIN1 = 1
}ErlNifCharEncoding;
+typedef struct
+{
+ ERL_NIF_TERM pid; /* internal, may change */
+}ErlNifPid;
+
typedef ErlDrvSysInfo ErlNifSysInfo;
typedef struct ErlDrvTid_ *ErlNifTid;
@@ -146,8 +157,6 @@ extern TWinDynNifCallbacks WinDynNifCallbacks;
#endif
-
-
#if (defined(__WIN32__) || defined(_WIN32) || defined(_WIN32_))
# define ERL_NIF_INIT_GLOB TWinDynNifCallbacks WinDynNifCallbacks;
# define ERL_NIF_INIT_DECL(MODNAME) __declspec(dllexport) ErlNifEntry* nif_init(TWinDynNifCallbacks* callbacks)
@@ -163,7 +172,18 @@ extern TWinDynNifCallbacks WinDynNifCallbacks;
#endif
+#ifdef __cplusplus
+}
+# define ERL_NIF_INIT_PROLOGUE extern "C" {
+# define ERL_NIF_INIT_EPILOGUE }
+#else
+# define ERL_NIF_INIT_PROLOGUE
+# define ERL_NIF_INIT_EPILOGUE
+#endif
+
+
#define ERL_NIF_INIT(NAME, FUNCS, LOAD, RELOAD, UPGRADE, UNLOAD) \
+ERL_NIF_INIT_PROLOGUE \
ERL_NIF_INIT_GLOB \
ERL_NIF_INIT_DECL(NAME) \
{ \
@@ -178,7 +198,9 @@ ERL_NIF_INIT_DECL(NAME) \
}; \
ERL_NIF_INIT_BODY; \
return &entry; \
-}
+} \
+ERL_NIF_INIT_EPILOGUE
+
#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 fe8d2664e1..ef4e9580b0 100644
--- a/erts/emulator/beam/erl_nif_api_funcs.h
+++ b/erts/emulator/beam/erl_nif_api_funcs.h
@@ -23,29 +23,29 @@
#ifdef ERL_NIF_API_FUNC_DECL
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(void*,enif_alloc,(size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_free,(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_alloc_binary,(size_t size, ErlNifBinary* bin));
+ERL_NIF_API_FUNC_DECL(int,enif_realloc_binary,(ErlNifBinary* bin, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_release_binary,(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(int,enif_is_identical,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs));
+ERL_NIF_API_FUNC_DECL(int,enif_compare,(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(int,enif_make_existing_atom,(ErlNifEnv* env, const char* name, ERL_NIF_TERM* atom, ErlNifCharEncoding));
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));
@@ -82,13 +82,13 @@ 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_realloc,(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(ERL_NIF_TERM,enif_make_sub_binary,(ErlNifEnv*, ERL_NIF_TERM bin_term, size_t pos, size_t 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_get_atom,(ErlNifEnv*, ERL_NIF_TERM atom, char* buf, unsigned len, ErlNifCharEncoding));
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));
@@ -99,13 +99,29 @@ 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(ErlNifResourceType*,enif_open_resource_type,(ErlNifEnv*, const char* module_str, const char* name_str, void (*dtor)(ErlNifEnv*,void *), ErlNifResourceFlags flags, ErlNifResourceFlags* tried));
+ERL_NIF_API_FUNC_DECL(void*,enif_alloc_resource,(ErlNifResourceType* type, size_t size));
+ERL_NIF_API_FUNC_DECL(void,enif_release_resource,(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));
-ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,unsigned size,ERL_NIF_TERM* termp));
+ERL_NIF_API_FUNC_DECL(size_t,enif_sizeof_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,size_t size,ERL_NIF_TERM* termp));
+ERL_NIF_API_FUNC_DECL(int,enif_is_list,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_is_tuple,(ErlNifEnv*, ERL_NIF_TERM term));
+ERL_NIF_API_FUNC_DECL(int,enif_get_atom_length,(ErlNifEnv*, ERL_NIF_TERM atom, unsigned* len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(int,enif_get_list_length,(ErlNifEnv* env, ERL_NIF_TERM term, unsigned* len));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM, enif_make_atom_len,(ErlNifEnv* env, const char* name, size_t len));
+ERL_NIF_API_FUNC_DECL(int, enif_make_existing_atom_len,(ErlNifEnv* env, const char* name, size_t len, ERL_NIF_TERM* atom, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_string_len,(ErlNifEnv* env, const char* string, size_t len, ErlNifCharEncoding));
+ERL_NIF_API_FUNC_DECL(ErlNifEnv*,enif_alloc_env,(void));
+ERL_NIF_API_FUNC_DECL(void,enif_free_env,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(void,enif_clear_env,(ErlNifEnv* env));
+ERL_NIF_API_FUNC_DECL(int,enif_send,(ErlNifEnv* env, const ErlNifPid* to_pid, ErlNifEnv* msg_env, ERL_NIF_TERM msg));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_copy,(ErlNifEnv* dst_env, ERL_NIF_TERM src_term));
+ERL_NIF_API_FUNC_DECL(ErlNifPid*,enif_self,(ErlNifEnv* caller_env, ErlNifPid* pid));
+ERL_NIF_API_FUNC_DECL(int,enif_get_local_pid,(ErlNifEnv* env, ERL_NIF_TERM, ErlNifPid* pid));
+ERL_NIF_API_FUNC_DECL(void,enif_keep_resource,(void* obj));
+ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_resource_binary,(ErlNifEnv*,void* obj,const void* data, size_t size));
/*
** Add last to keep compatibility on Windows!!!
@@ -198,6 +214,22 @@ ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,unsigned s
# define enif_get_resource ERL_NIF_API_FUNC_MACRO(enif_get_resource)
# define enif_sizeof_resource ERL_NIF_API_FUNC_MACRO(enif_sizeof_resource)
# define enif_make_new_binary ERL_NIF_API_FUNC_MACRO(enif_make_new_binary)
+# define enif_is_list ERL_NIF_API_FUNC_MACRO(enif_is_list)
+# define enif_is_tuple ERL_NIF_API_FUNC_MACRO(enif_is_tuple)
+# define enif_get_atom_length ERL_NIF_API_FUNC_MACRO(enif_get_atom_length)
+# define enif_get_list_length ERL_NIF_API_FUNC_MACRO(enif_get_list_length)
+# define enif_make_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_atom_len)
+# define enif_make_existing_atom_len ERL_NIF_API_FUNC_MACRO(enif_make_existing_atom_len)
+# define enif_make_string_len ERL_NIF_API_FUNC_MACRO(enif_make_string_len)
+# define enif_alloc_env ERL_NIF_API_FUNC_MACRO(enif_alloc_env)
+# define enif_free_env ERL_NIF_API_FUNC_MACRO(enif_free_env)
+# define enif_clear_env ERL_NIF_API_FUNC_MACRO(enif_clear_env)
+# define enif_send ERL_NIF_API_FUNC_MACRO(enif_send)
+# define enif_make_copy ERL_NIF_API_FUNC_MACRO(enif_make_copy)
+# define enif_self ERL_NIF_API_FUNC_MACRO(enif_self)
+# define enif_get_local_pid ERL_NIF_API_FUNC_MACRO(enif_get_local_pid)
+# define enif_keep_resource ERL_NIF_API_FUNC_MACRO(enif_keep_resource)
+# define enif_make_resource_binary ERL_NIF_API_FUNC_MACRO(enif_make_resource_binary)
#endif
#ifndef enif_make_list1
@@ -219,9 +251,7 @@ ERL_NIF_API_FUNC_DECL(unsigned char*,enif_make_new_binary,(ErlNifEnv*,unsigned s
# 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 */
+# define enif_make_pid(ENV, PID) ((const ERL_NIF_TERM)((PID)->pid))
#endif
diff --git a/erts/emulator/beam/erl_port_task.c b/erts/emulator/beam/erl_port_task.c
index 0b6bb0d8e9..967a14f0d1 100644
--- a/erts/emulator/beam/erl_port_task.c
+++ b/erts/emulator/beam/erl_port_task.c
@@ -969,11 +969,11 @@ erts_port_task_execute(ErtsRunQueue *runq, Port **curr_port_pp)
erts_port_release(pp);
#else
{
- long refc = erts_smp_atomic_dectest(&pp->refc);
+ long refc;
+ erts_smp_mtx_unlock(pp->lock);
+ refc = erts_smp_atomic_dectest(&pp->refc);
ASSERT(refc >= 0);
- if (refc > 0)
- erts_smp_mtx_unlock(pp->lock);
- else {
+ if (refc == 0) {
erts_smp_runq_unlock(runq);
erts_port_cleanup(pp); /* Might aquire runq lock */
erts_smp_runq_lock(runq);
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 11ca85a41c..055733ac49 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -180,6 +180,7 @@ static ErtsCpuBindData *scheduler2cpu_map;
erts_smp_rwmtx_t erts_cpu_bind_rwmtx;
typedef enum {
+ ERTS_CPU_BIND_UNDEFINED,
ERTS_CPU_BIND_SPREAD,
ERTS_CPU_BIND_PROCESSOR_SPREAD,
ERTS_CPU_BIND_THREAD_SPREAD,
@@ -190,6 +191,9 @@ typedef enum {
ERTS_CPU_BIND_NONE
} ErtsCpuBindOrder;
+#define ERTS_CPU_BIND_DEFAULT_BIND \
+ ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD
+
ErtsCpuBindOrder cpu_bind_order;
static erts_cpu_topology_t *user_cpudata;
@@ -2078,12 +2082,14 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
erts_aligned_run_queues = erts_alloc(ERTS_ALC_T_RUNQS,
(sizeof(ErtsAlignedRunQueue)*(n+1)));
- if ((((UWord) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) == 0)
+ if ((((UWord) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) != 0)
erts_aligned_run_queues = ((ErtsAlignedRunQueue *)
((((UWord) erts_aligned_run_queues)
& ~ERTS_CACHE_LINE_MASK)
+ ERTS_CACHE_LINE_SIZE));
+ ASSERT((((UWord) erts_aligned_run_queues) & ERTS_CACHE_LINE_MASK) == 0);
+
#ifdef ERTS_SMP
erts_smp_atomic_init(&no_empty_run_queues, 0);
#endif
@@ -2175,11 +2181,14 @@ erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online)
erts_aligned_scheduler_data = erts_alloc(ERTS_ALC_T_SCHDLR_DATA,
(sizeof(ErtsAlignedSchedulerData)
*(n+1)));
- if ((((UWord) erts_aligned_scheduler_data) & ERTS_CACHE_LINE_MASK) == 0)
+ if ((((UWord) erts_aligned_scheduler_data) & ERTS_CACHE_LINE_MASK) != 0)
erts_aligned_scheduler_data = ((ErtsAlignedSchedulerData *)
((((UWord) erts_aligned_scheduler_data)
& ~ERTS_CACHE_LINE_MASK)
+ ERTS_CACHE_LINE_SIZE));
+
+ ASSERT((((UWord) erts_aligned_scheduler_data) & ERTS_CACHE_LINE_MASK) == 0);
+
for (ix = 0; ix < n; ix++) {
ErtsSchedulerData *esdp = ERTS_SCHEDULER_IX(ix);
#ifdef ERTS_SMP
@@ -2769,7 +2778,7 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all)
res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */
}
else if (on) { /* ------ BLOCK ------ */
- if (erts_is_multi_scheduling_blocked()) {
+ if (schdlr_sspnd.msb.procs) {
plp = proclist_create(p);
plp->next = schdlr_sspnd.msb.procs;
schdlr_sspnd.msb.procs = plp;
@@ -2975,8 +2984,11 @@ erts_dbg_multi_scheduling_return_trap(Process *p, Eterm return_value)
int
erts_is_multi_scheduling_blocked(void)
{
- return (erts_smp_atomic_read(&schdlr_sspnd.msb.ongoing)
- && erts_smp_atomic_read(&schdlr_sspnd.active) == 1);
+ int res;
+ erts_smp_mtx_lock(&schdlr_sspnd.mtx);
+ res = schdlr_sspnd.msb.procs != NULL;
+ erts_smp_mtx_unlock(&schdlr_sspnd.mtx);
+ return res;
}
Eterm
@@ -2985,7 +2997,7 @@ erts_multi_scheduling_blockers(Process *p)
Eterm res = NIL;
erts_smp_mtx_lock(&schdlr_sspnd.mtx);
- if (erts_is_multi_scheduling_blocked()) {
+ if (schdlr_sspnd.msb.procs) {
Eterm *hp, *hp_end;
ErtsProcList *plp1, *plp2;
Uint max_size;
@@ -3503,14 +3515,15 @@ erts_init_scheduler_bind_type(char *how)
if (!system_cpudata && !user_cpudata)
return ERTS_INIT_SCHED_BIND_TYPE_ERROR_NO_CPU_TOPOLOGY;
- if (sys_strcmp(how, "s") == 0)
+ if (sys_strcmp(how, "db") == 0)
+ cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND;
+ else if (sys_strcmp(how, "s") == 0)
cpu_bind_order = ERTS_CPU_BIND_SPREAD;
else if (sys_strcmp(how, "ps") == 0)
cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD;
else if (sys_strcmp(how, "ts") == 0)
cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD;
- else if (sys_strcmp(how, "db") == 0
- || sys_strcmp(how, "tnnps") == 0)
+ else if (sys_strcmp(how, "tnnps") == 0)
cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD;
else if (sys_strcmp(how, "nnps") == 0)
cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD;
@@ -4153,14 +4166,15 @@ erts_bind_schedulers(Process *c_p, Eterm how)
old_cpu_bind_order = cpu_bind_order;
- if (ERTS_IS_ATOM_STR("spread", how))
+ if (ERTS_IS_ATOM_STR("default_bind", how))
+ cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND;
+ else if (ERTS_IS_ATOM_STR("spread", how))
cpu_bind_order = ERTS_CPU_BIND_SPREAD;
else if (ERTS_IS_ATOM_STR("processor_spread", how))
cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD;
else if (ERTS_IS_ATOM_STR("thread_spread", how))
cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD;
- else if (ERTS_IS_ATOM_STR("default_bind", how)
- || ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how))
+ else if (ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how))
cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD;
else if (ERTS_IS_ATOM_STR("no_node_processor_spread", how))
cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD;
@@ -4206,14 +4220,15 @@ erts_fake_scheduler_bindings(Process *p, Eterm how)
int cpudata_size;
Eterm res;
- if (ERTS_IS_ATOM_STR("spread", how))
+ if (ERTS_IS_ATOM_STR("default_bind", how))
+ fake_cpu_bind_order = ERTS_CPU_BIND_DEFAULT_BIND;
+ else if (ERTS_IS_ATOM_STR("spread", how))
fake_cpu_bind_order = ERTS_CPU_BIND_SPREAD;
else if (ERTS_IS_ATOM_STR("processor_spread", how))
fake_cpu_bind_order = ERTS_CPU_BIND_PROCESSOR_SPREAD;
else if (ERTS_IS_ATOM_STR("thread_spread", how))
fake_cpu_bind_order = ERTS_CPU_BIND_THREAD_SPREAD;
- else if (ERTS_IS_ATOM_STR("default_bind", how)
- || ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how))
+ else if (ERTS_IS_ATOM_STR("thread_no_node_processor_spread", how))
fake_cpu_bind_order = ERTS_CPU_BIND_THREAD_NO_NODE_PROCESSOR_SPREAD;
else if (ERTS_IS_ATOM_STR("no_node_processor_spread", how))
fake_cpu_bind_order = ERTS_CPU_BIND_NO_NODE_PROCESSOR_SPREAD;
@@ -4438,7 +4453,7 @@ early_cpu_bind_init(void)
(sizeof(erts_cpu_topology_t)
* system_cpudata_size));
- cpu_bind_order = ERTS_CPU_BIND_NONE;
+ cpu_bind_order = ERTS_CPU_BIND_UNDEFINED;
if (!erts_get_cpu_topology(erts_cpuinfo, system_cpudata)
|| ERTS_INIT_CPU_TOPOLOGY_OK != verify_topology(system_cpudata,
@@ -4464,6 +4479,17 @@ late_cpu_bind_init(void)
scheduler2cpu_map[ix].bound_id = -1;
}
+ if (cpu_bind_order == ERTS_CPU_BIND_UNDEFINED) {
+ int ncpus = erts_get_cpu_configured(erts_cpuinfo);
+ if (ncpus < 1 || erts_no_schedulers < ncpus)
+ cpu_bind_order = ERTS_CPU_BIND_NONE;
+ else
+ cpu_bind_order = ((system_cpudata || user_cpudata)
+ && (erts_bind_to_cpu(erts_cpuinfo, -1) != -ENOTSUP)
+ ? ERTS_CPU_BIND_DEFAULT_BIND
+ : ERTS_CPU_BIND_NONE);
+ }
+
if (cpu_bind_order != ERTS_CPU_BIND_NONE) {
erts_cpu_topology_t *cpudata;
int cpudata_size;
@@ -7187,8 +7213,6 @@ erts_debug_verify_clean_empty_process(Process* p)
void
erts_cleanup_empty_process(Process* p)
{
- ErlHeapFragment* mbufp;
-
/* We only check fields that are known to be used... */
erts_cleanup_offheap(&p->off_heap);
@@ -7199,13 +7223,10 @@ erts_cleanup_empty_process(Process* p)
p->off_heap.externals = NULL;
p->off_heap.overhead = 0;
- mbufp = p->mbuf;
- while (mbufp) {
- ErlHeapFragment *next = mbufp->next;
- free_message_buffer(mbufp);
- mbufp = next;
+ if (p->mbuf != NULL) {
+ free_message_buffer(p->mbuf);
+ p->mbuf = NULL;
}
- p->mbuf = NULL;
#if defined(ERTS_ENABLE_LOCK_COUNT) && defined(ERTS_SMP)
erts_lcnt_proc_lock_destroy(p);
#endif
@@ -7221,7 +7242,6 @@ static void
delete_process(Process* p)
{
ErlMessage* mp;
- ErlHeapFragment* bp;
VERBOSE(DEBUG_PROCESSES, ("Removing process: %T\n",p->id));
@@ -7271,11 +7291,8 @@ delete_process(Process* p)
/*
* Free all pending message buffers.
*/
- bp = p->mbuf;
- while (bp != NULL) {
- ErlHeapFragment* next_bp = bp->next;
- free_message_buffer(bp);
- bp = next_bp;
+ if (p->mbuf != NULL) {
+ free_message_buffer(p->mbuf);
}
erts_erase_dicts(p);
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index cbcdec4ba7..e2cb523cf5 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -765,7 +765,7 @@ 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));
+ ASSERT(hf!=NULL && (hp - hf->mem < (unsigned long)hf->alloc_size));
hf->used_size = hp - hf->mem;
}
diff --git a/erts/emulator/beam/erl_threads.h b/erts/emulator/beam/erl_threads.h
index d635916dd8..21f85bd045 100644
--- a/erts/emulator/beam/erl_threads.h
+++ b/erts/emulator/beam/erl_threads.h
@@ -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%
*/
@@ -34,6 +34,8 @@
#include "erl_lock_count.h"
#include "erl_term.h"
+#define ERTS_THR_MEMORY_BARRIER ETHR_MEMORY_BARRIER
+
#ifdef ERTS_ENABLE_LOCK_COUNT
#define erts_mtx_lock(L) erts_mtx_lock_x(L, __FILE__, __LINE__)
#define erts_spin_lock(L) erts_spin_lock_x(L, __FILE__, __LINE__)
@@ -122,6 +124,8 @@ __decl_noreturn void __noreturn erts_thr_fatal_error(int, char *);
#else /* #ifdef USE_THREADS */
+#define ERTS_THR_MEMORY_BARRIER
+
#define ERTS_THR_OPTS_DEFAULT_INITER 0
typedef int erts_thr_opts_t;
typedef int erts_thr_init_data_t;
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 8addfcf5ad..381a182e39 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -1941,11 +1941,13 @@ trace_proc(Process *c_p, Process *t_p, Eterm what, Eterm data)
Eterm* hp;
int need;
+ ERTS_SMP_LC_ASSERT((erts_proc_lc_my_proc_locks(t_p) != 0) || erts_is_system_blocked(0));
if (is_internal_port(t_p->tracer_proc)) {
#define LOCAL_HEAP_SIZE (5+5)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
UseTmpHeapNoproc(LOCAL_HEAP_SIZE);
+
hp = local_heap;
mess = TUPLE4(hp, am_trace, t_p->id, what, data);
hp += 5;
@@ -2727,6 +2729,8 @@ trace_port(Port *t_p, Eterm what, Eterm data) {
Eterm mess;
Eterm* hp;
+ ERTS_SMP_LC_ASSERT(erts_lc_is_port_locked(t_p) || erts_is_system_blocked(0));
+
if (is_internal_port(t_p->tracer_proc)) {
#define LOCAL_HEAP_SIZE (5+5)
DeclareTmpHeapNoproc(local_heap,LOCAL_HEAP_SIZE);
diff --git a/erts/emulator/beam/erl_vm.h b/erts/emulator/beam/erl_vm.h
index 235bd7931d..cd63401581 100644
--- a/erts/emulator/beam/erl_vm.h
+++ b/erts/emulator/beam/erl_vm.h
@@ -61,8 +61,9 @@
/*
* The new arithmetic operations need some extra X registers in the register array.
+ * so does the gc_bif's (i_gc_bif3 need 3 extra).
*/
-#define ERTS_X_REGS_ALLOCATED (MAX_REG+2)
+#define ERTS_X_REGS_ALLOCATED (MAX_REG+3)
#define INPUT_REDUCTIONS (2 * CONTEXT_REDS)
@@ -83,6 +84,7 @@
#define ErtsHAllocLockCheck(P) \
ERTS_SMP_LC_ASSERT((ERTS_PROC_LOCK_MAIN & erts_proc_lc_my_proc_locks((P))) \
+ || ((P)->id == ERTS_INVALID_PID) \
|| ((P)->scheduler_data \
&& (P) == (P)->scheduler_data->match_pseudo_process) \
|| erts_is_system_blocked(0))
diff --git a/erts/emulator/beam/global.h b/erts/emulator/beam/global.h
index fbb40e4202..19dd3d6f97 100644
--- a/erts/emulator/beam/global.h
+++ b/erts/emulator/beam/global.h
@@ -881,6 +881,8 @@ Eterm copy_object(Eterm, Process*);
Uint size_object(Eterm);
Eterm copy_struct(Eterm, Uint, Eterm**, ErlOffHeap*);
Eterm copy_shallow(Eterm*, Uint, Eterm**, ErlOffHeap*);
+void move_multi_frags(Eterm** hpp, ErlOffHeap*, ErlHeapFragment* first,
+ Eterm* refs, unsigned nrefs);
#ifdef HYBRID
#define RRMA_DEFAULT_SIZE 256
@@ -1078,6 +1080,7 @@ Eterm erts_heap_sizes(Process* p);
void erts_offset_off_heap(ErlOffHeap *, Sint, Eterm*, Eterm*);
void erts_offset_heap_ptr(Eterm*, Uint, Sint, Eterm*, Eterm*);
void erts_offset_heap(Eterm*, Uint, Sint, Eterm*, Eterm*);
+void erts_free_heap_frags(Process* p);
#ifdef HYBRID
int erts_global_garbage_collect(Process*, int, Eterm*, int);
@@ -1192,12 +1195,11 @@ erts_smp_port_unlock(Port *prt)
{
#ifdef ERTS_SMP
long refc;
+ erts_smp_mtx_unlock(prt->lock);
refc = erts_smp_atomic_dectest(&prt->refc);
ASSERT(refc >= 0);
if (refc == 0)
erts_port_cleanup(prt);
- else
- erts_smp_mtx_unlock(prt->lock);
#endif
}
@@ -1576,6 +1578,10 @@ void erts_init_bif_chksum(void);
/* erl_bif_re.c */
void erts_init_bif_re(void);
Sint erts_re_set_loop_limit(Sint limit);
+/* erl_bif_binary.c */
+void erts_init_bif_binary(void);
+Sint erts_binary_set_loop_limit(Sint limit);
+
/* erl_unicode.c */
void erts_init_unicode(void);
Sint erts_unicode_set_loop_limit(Sint limit);
@@ -1705,6 +1711,8 @@ Eterm erts_gc_abs_1(Process* p, Eterm* reg, Uint live);
Eterm erts_gc_float_1(Process* p, Eterm* reg, Uint live);
Eterm erts_gc_round_1(Process* p, Eterm* reg, Uint live);
Eterm erts_gc_trunc_1(Process* p, Eterm* reg, Uint live);
+Eterm erts_gc_binary_part_3(Process* p, Eterm* reg, Uint live);
+Eterm erts_gc_binary_part_2(Process* p, Eterm* reg, Uint live);
Uint erts_current_reductions(Process* current, Process *p);
@@ -1714,7 +1722,6 @@ int erts_print_system_version(int to, void *arg, Process *c_p);
* Interface to erl_init
*/
void erl_init(void);
-void erts_first_process(Eterm modname, void* code, unsigned size, int argc, char** argv);
#define seq_trace_output(token, msg, type, receiver, process) \
seq_trace_output_generic((token), (msg), (type), (receiver), (process), NIL)
diff --git a/erts/emulator/beam/io.c b/erts/emulator/beam/io.c
index 10f1082039..68625801cf 100644
--- a/erts/emulator/beam/io.c
+++ b/erts/emulator/beam/io.c
@@ -280,10 +280,36 @@ erts_test_next_port(int set, Uint next)
return res;
}
+
+static void port_cleanup(Port *prt);
+
+#ifdef ERTS_SMP
+
+static void
+sched_port_cleanup(void *vprt)
+{
+ Port *prt = (Port *) vprt;
+ erts_smp_mtx_lock(prt->lock);
+ port_cleanup(prt);
+}
+
+#endif
+
void
erts_port_cleanup(Port *prt)
{
#ifdef ERTS_SMP
+ if (erts_smp_mtx_trylock(prt->lock) == EBUSY)
+ erts_schedule_misc_op(sched_port_cleanup, (void *) prt);
+ else
+#endif
+ port_cleanup(prt);
+}
+
+void
+port_cleanup(Port *prt)
+{
+#ifdef ERTS_SMP
Uint32 port_specific;
erts_smp_mtx_t *mtx;
#endif
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index 9e8ac74f40..42c84989c6 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -60,12 +60,18 @@ func_info M=a a==am_module_info A=u==0 | label L | move n r => too_old_compiler
func_info M=a a==am_module_info A=u==1 | label L | move n r => too_old_compiler
# The undocumented and unsupported guard BIF is_constant/1 was removed
-# in R13. The is_constant/2 operation is marked as obosolete in genop.tab,
+# in R13. The is_constant/2 operation is marked as obsolete in genop.tab,
# so the loader will automatically generate a too_old_compiler message
# it is used, but we need to handle the is_constant/1 BIF specially here.
bif1 Fail u$func:erlang:is_constant/1 Src Dst => too_old_compiler
+# Since the constant pool was introduced in R12B, empty tuples ({})
+# are literals. Therefore we no longer need to allow put_tuple/2
+# with a tuple size of zero.
+
+put_tuple u==0 d => too_old_compiler
+
#
# All the other instructions.
#
@@ -328,11 +334,8 @@ i_is_eq_immed f y c
# Putting things.
#
-put_tuple u==0 Dst => i_put_tuple_only u Dst
put_tuple Arity Dst | put V => i_put_tuple Arity V Dst
-i_put_tuple_only A d
-
%macro: i_put_tuple PutTuple -pack
i_put_tuple A x x
i_put_tuple A y x
@@ -1177,12 +1180,6 @@ i_bs_init_bits_fail_heap I j I d
i_bs_init_bits I I d
i_bs_init_bits_heap I I I d
-bs_bits_to_bytes Fail Src Dst => i_bs_bits_to_bytes Src Fail Dst
-
-i_bs_bits_to_bytes r j d
-i_bs_bits_to_bytes x j d
-i_bs_bits_to_bytes y j d
-
bs_add Fail S1=i==0 S2 Unit=u==1 D => move S2 D
bs_add Fail S1 S2 Unit D => i_fetch S1 S2 | i_bs_add Fail Unit D
@@ -1390,34 +1387,60 @@ bif1 Fail u$bif:erlang:trunc/1 s d => too_old_compiler
# Guard BIFs.
#
gc_bif1 Fail I Bif=u$bif:erlang:length/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
gc_bif1 Fail I Bif=u$bif:erlang:size/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
gc_bif1 Fail I Bif=u$bif:erlang:bit_size/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
gc_bif1 Fail I Bif=u$bif:erlang:byte_size/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
gc_bif1 Fail I Bif=u$bif:erlang:abs/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
gc_bif1 Fail I Bif=u$bif:erlang:float/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
gc_bif1 Fail I Bif=u$bif:erlang:round/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
gc_bif1 Fail I Bif=u$bif:erlang:trunc/1 Src Dst=d => \
- gen_guard_bif(Fail, I, Bif, Src, Dst)
+ gen_guard_bif1(Fail, I, Bif, Src, Dst)
+
+gc_bif2 Fail I Bif=u$bif:erlang:binary_part/2 S1 S2 Dst=d => \
+ gen_guard_bif2(Fail, I, Bif, S1, S2, Dst)
+
+gc_bif3 Fail I Bif=u$bif:erlang:binary_part/3 S1 S2 S3 Dst=d => \
+ gen_guard_bif3(Fail, I, Bif, S1, S2, S3, Dst)
i_gc_bif1 Fail Bif V=q Live D => move V x | i_gc_bif1 Fail Bif x Live D
i_gc_bif1 j I s I d
+ii_gc_bif2/6
+
+ii_gc_bif2 Fail Bif S1 S2 Live D => i_fetch S1 S2 | i_gc_bif2 Fail Bif Live D
+
+i_gc_bif2 j I I d
+
+ii_gc_bif3/7
+
+ii_gc_bif3 Fail Bif S1 S2 S3 Live D => move S1 x | i_fetch S2 S3 | i_gc_bif3 Fail Bif x Live D
+
+i_gc_bif3 j I s I d
#
# R13B03
#
on_load
+
+#
+# R14A.
+#
+recv_mark f
+
+recv_set Fail | label Lbl | loop_rec Lf Reg => \
+ i_recv_set | label Lbl | loop_rec Lf Reg
+i_recv_set
diff --git a/erts/emulator/beam/register.c b/erts/emulator/beam/register.c
index 964c10a380..900ebcbbf7 100644
--- a/erts/emulator/beam/register.c
+++ b/erts/emulator/beam/register.c
@@ -476,8 +476,9 @@ int erts_unregister_name(Process *c_p,
* on c_prt.
*/
- if (!c_p)
+ if (!c_p) {
c_p_locks = 0;
+ }
current_c_p_locks = c_p_locks;
restart:
@@ -489,9 +490,15 @@ int erts_unregister_name(Process *c_p,
if (is_non_value(name)) {
/* Unregister current process name */
ASSERT(c_p);
- if (c_p->reg)
+#ifdef ERTS_SMP
+ if (current_c_p_locks != c_p_locks) {
+ erts_smp_proc_lock(c_p, c_p_locks);
+ current_c_p_locks = c_p_locks;
+ }
+#endif
+ if (c_p->reg) {
r.name = c_p->reg->name;
- else {
+ } else {
/* Name got unregistered while main lock was released */
res = 0;
goto done;
@@ -533,24 +540,25 @@ int erts_unregister_name(Process *c_p,
}
} else if (rp->p) {
- Process* p = rp->p;
+
#ifdef ERTS_SMP
erts_proc_safelock(c_p,
current_c_p_locks,
c_p_locks,
rp->p,
- 0,
+ (c_p == rp->p) ? current_c_p_locks : 0,
ERTS_PROC_LOCK_MAIN);
current_c_p_locks = c_p_locks;
#endif
- p->reg = NULL;
+ rp->p->reg = NULL;
+ if (IS_TRACED_FL(rp->p, F_TRACE_PROCS)) {
+ trace_proc(c_p, rp->p, am_unregister, r.name);
+ }
#ifdef ERTS_SMP
- if (rp->p != c_p)
+ if (rp->p != c_p) {
erts_smp_proc_unlock(rp->p, ERTS_PROC_LOCK_MAIN);
-#endif
- if (IS_TRACED_FL(p, F_TRACE_PROCS)) {
- trace_proc(c_p, p, am_unregister, r.name);
}
+#endif
}
hash_erase(&process_reg, (void*) &r);
res = 1;
@@ -560,14 +568,17 @@ int erts_unregister_name(Process *c_p,
reg_write_unlock();
if (c_prt != port) {
- if (port)
+ if (port) {
erts_smp_port_unlock(port);
- if (c_prt)
+ }
+ if (c_prt) {
erts_smp_port_lock(c_prt);
+ }
}
#ifdef ERTS_SMP
- if (c_p && !current_c_p_locks)
+ if (c_p && !current_c_p_locks) {
erts_smp_proc_lock(c_p, c_p_locks);
+ }
#endif
return res;
}
diff --git a/erts/emulator/beam/sys.h b/erts/emulator/beam/sys.h
index a1955235b7..ca87d3d70f 100644
--- a/erts/emulator/beam/sys.h
+++ b/erts/emulator/beam/sys.h
@@ -648,7 +648,7 @@ extern char *erts_sys_ddll_error(int code);
/*
- * System interfaces for startup/sae code (functions found in respective sys.c)
+ * System interfaces for startup.
*/
@@ -1173,14 +1173,14 @@ EXTERN_FUNCTION(void*, sys_calloc2, (Uint, Uint));
/* Standard set of integer macros .. */
-#define get_int64(s) ((((unsigned char*) (s))[0] << 56) | \
- (((unsigned char*) (s))[1] << 48) | \
- (((unsigned char*) (s))[2] << 40) | \
- (((unsigned char*) (s))[3] << 32) | \
- (((unsigned char*) (s))[4] << 24) | \
- (((unsigned char*) (s))[5] << 16) | \
- (((unsigned char*) (s))[6] << 8) | \
- (((unsigned char*) (s))[7]))
+#define get_int64(s) (((Uint64)(((unsigned char*) (s))[0]) << 56) | \
+ (((Uint64)((unsigned char*) (s))[1]) << 48) | \
+ (((Uint64)((unsigned char*) (s))[2]) << 40) | \
+ (((Uint64)((unsigned char*) (s))[3]) << 32) | \
+ (((Uint64)((unsigned char*) (s))[4]) << 24) | \
+ (((Uint64)((unsigned char*) (s))[5]) << 16) | \
+ (((Uint64)((unsigned char*) (s))[6]) << 8) | \
+ (((Uint64)((unsigned char*) (s))[7])))
#define put_int64(i, s) do {((char*)(s))[0] = (char)((Sint64)(i) >> 56) & 0xff;\
((char*)(s))[1] = (char)((Sint64)(i) >> 48) & 0xff;\
diff --git a/erts/emulator/beam/utils.c b/erts/emulator/beam/utils.c
index 51c12a0b69..445a8eebd9 100644
--- a/erts/emulator/beam/utils.c
+++ b/erts/emulator/beam/utils.c
@@ -32,6 +32,7 @@
#include "erl_binary.h"
#include "erl_bits.h"
#include "packet_parser.h"
+#include "erl_gc.h"
#define ERTS_WANT_DB_INTERNAL__
#include "erl_db.h"
#include "erl_threads.h"
@@ -125,7 +126,7 @@ erts_heap_alloc(Process* p, Uint need)
n = need;
bp = MBUF(p);
- if (bp != NULL && need <= (bp->size - bp->used_size)) {
+ if (bp != NULL && need <= (bp->alloc_size - bp->used_size)) {
Eterm* ret = bp->mem + bp->used_size;
bp->used_size += need;
return ret;
@@ -158,7 +159,7 @@ erts_heap_alloc(Process* p, Uint need)
bp->next = MBUF(p);
MBUF(p) = bp;
- bp->size = n;
+ bp->alloc_size = n;
bp->used_size = n;
MBUF_SIZE(p) += n;
bp->off_heap.mso = NULL;
diff --git a/erts/emulator/drivers/common/efile_drv.c b/erts/emulator/drivers/common/efile_drv.c
index d2b916000e..60ae4cb108 100644
--- a/erts/emulator/drivers/common/efile_drv.c
+++ b/erts/emulator/drivers/common/efile_drv.c
@@ -53,6 +53,8 @@
#define FILE_IPREAD 27
#define FILE_ALTNAME 28
#define FILE_READ_LINE 29
+#define FILE_FDATASYNC 30
+#define FILE_FADVISE 31
/* Return codes */
@@ -357,6 +359,11 @@ struct t_data
struct t_readdir_buf *first_buf;
struct t_readdir_buf *last_buf;
} read_dir;
+ struct {
+ Sint64 offset;
+ Sint64 length;
+ int advise;
+ } fadvise;
} c;
char b[1];
};
@@ -883,6 +890,15 @@ static void invoke_chdir(void *data)
invoke_name(data, efile_chdir);
}
+static void invoke_fdatasync(void *data)
+{
+ struct t_data *d = (struct t_data *) data;
+ int fd = (int) d->fd;
+
+ d->again = 0;
+ d->result_ok = efile_fdatasync(&d->errInfo, fd);
+}
+
static void invoke_fsync(void *data)
{
struct t_data *d = (struct t_data *) data;
@@ -1637,6 +1653,18 @@ static void invoke_open(void *data)
d->result_ok = status;
}
+static void invoke_fadvise(void *data)
+{
+ struct t_data *d = (struct t_data *) data;
+ int fd = (int) d->fd;
+ off_t offset = (off_t) d->c.fadvise.offset;
+ off_t length = (off_t) d->c.fadvise.length;
+ int advise = (int) d->c.fadvise.advise;
+
+ d->again = 0;
+ d->result_ok = efile_fadvise(&d->errInfo, fd, offset, length, advise);
+}
+
static void free_readdir(void *data)
{
struct t_data *d = (struct t_data *) data;
@@ -1919,12 +1947,14 @@ file_async_ready(ErlDrvData e, ErlDrvThreadData data)
case FILE_RMDIR:
case FILE_CHDIR:
case FILE_DELETE:
+ case FILE_FDATASYNC:
case FILE_FSYNC:
case FILE_TRUNCATE:
case FILE_LINK:
case FILE_SYMLINK:
case FILE_RENAME:
case FILE_WRITE_INFO:
+ case FILE_FADVISE:
reply(desc, d->result_ok, &d->errInfo);
free_data(data);
break;
@@ -2209,6 +2239,18 @@ file_output(ErlDrvData e, char* buf, int count)
goto done;
}
+ case FILE_FDATASYNC:
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data));
+
+ d->fd = fd;
+ d->command = command;
+ d->invoke = invoke_fdatasync;
+ d->free = free_data;
+ d->level = 2;
+ goto done;
+ }
+
case FILE_FSYNC:
{
d = EF_SAFE_ALLOC(sizeof(struct t_data));
@@ -2332,6 +2374,21 @@ file_output(ErlDrvData e, char* buf, int count)
goto done;
}
+ case FILE_FADVISE:
+ {
+ d = EF_SAFE_ALLOC(sizeof(struct t_data));
+
+ d->fd = fd;
+ d->command = command;
+ d->invoke = invoke_fadvise;
+ d->free = free_data;
+ d->level = 2;
+ d->c.fadvise.offset = get_int64((uchar*) buf);
+ d->c.fadvise.length = get_int64(((uchar*) buf) + sizeof(Sint64));
+ d->c.fadvise.advise = get_int32(((uchar*) buf) + 2 * sizeof(Sint64));
+ goto done;
+ }
+
}
/*
diff --git a/erts/emulator/drivers/common/erl_efile.h b/erts/emulator/drivers/common/erl_efile.h
index 9aa941e550..bbc973d58b 100644
--- a/erts/emulator/drivers/common/erl_efile.h
+++ b/erts/emulator/drivers/common/erl_efile.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%
*/
/*
@@ -126,6 +126,7 @@ int efile_readdir(Efile_error* errInfo, char* name,
int efile_openfile(Efile_error* errInfo, char* name, int flags,
int* pfd, Sint64* pSize);
void efile_closefile(int fd);
+int efile_fdatasync(Efile_error* errInfo, int fd);
int efile_fsync(Efile_error* errInfo, int fd);
int efile_fileinfo(Efile_error* errInfo, Efile_info* pInfo,
char *name, int info_for_link);
@@ -150,3 +151,5 @@ int efile_altname(Efile_error* errInfo, char *name,
int efile_link(Efile_error* errInfo, char* old, char* new);
int efile_symlink(Efile_error* errInfo, char* old, char* new);
int efile_may_openfile(Efile_error* errInfo, char *name);
+int efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset, Sint64 length,
+ int advise);
diff --git a/erts/emulator/drivers/common/inet_drv.c b/erts/emulator/drivers/common/inet_drv.c
index e8456cc616..87691fc1bc 100644
--- a/erts/emulator/drivers/common/inet_drv.c
+++ b/erts/emulator/drivers/common/inet_drv.c
@@ -55,6 +55,21 @@
#include "erl_driver.h"
+/* The IS_SOCKET_ERROR macro below is used for portability reasons. While
+ POSIX specifies that errors from socket-related system calls should be
+ indicated with a -1 return value, some users have experienced non-Windows
+ OS kernels that return negative values other than -1. While one can argue
+ that such kernels are technically broken, comparing against values less
+ than 0 covers their out-of-spec return values without imposing incorrect
+ semantics on systems that manage to correctly return -1 for errors, thus
+ increasing Erlang's portability.
+*/
+#ifdef __WIN32__
+#define IS_SOCKET_ERROR(val) ((val) == SOCKET_ERROR)
+#else
+#define IS_SOCKET_ERROR(val) ((val) < 0)
+#endif
+
#ifdef __WIN32__
#define STRNCASECMP strncasecmp
@@ -279,7 +294,7 @@ static int (*p_sctp_bindx)(int sd, struct sockaddr *addrs,
#define DEBUGF(X) printf X
#endif
-#if !defined(__WIN32__) && !defined(HAVE_STRNCASECMP)
+#if !defined(HAVE_STRNCASECMP)
#define STRNCASECMP my_strncasecmp
static int my_strncasecmp(const char *s1, const char *s2, size_t n)
@@ -299,6 +314,7 @@ static int my_strncasecmp(const char *s1, const char *s2, size_t n)
#define INVALID_SOCKET -1
#define INVALID_EVENT -1
#define SOCKET_ERROR -1
+
#define SOCKET int
#define HANDLE long int
#define FD_READ ERL_DRV_READ
@@ -3684,7 +3700,7 @@ static int inet_ctl_fdopen(inet_descriptor* desc, int domain, int type,
unsigned int sz = sizeof(name);
/* check that it is a socket and that the socket is bound */
- if (sock_name(s, (struct sockaddr*) &name, &sz) == SOCKET_ERROR)
+ if (IS_SOCKET_ERROR(sock_name(s, (struct sockaddr*) &name, &sz)))
return ctl_error(sock_errno(), rbuf, rsize);
desc->s = s;
if ((desc->event = sock_create_event(desc)) == INVALID_EVENT)
@@ -3696,7 +3712,7 @@ static int inet_ctl_fdopen(inet_descriptor* desc, int domain, int type,
desc->state = INET_STATE_BOUND; /* assume bound */
if (type == SOCK_STREAM) { /* check if connected */
sz = sizeof(name);
- if (sock_peer(s, (struct sockaddr*) &name, &sz) != SOCKET_ERROR)
+ if (!IS_SOCKET_ERROR(sock_peer(s, (struct sockaddr*) &name, &sz)))
desc->state = INET_STATE_CONNECTED;
}
@@ -5627,8 +5643,8 @@ static int inet_fill_opts(inet_descriptor* desc,
buf += arg_sz;
len -= arg_sz;
}
- if (sock_getopt(desc->s,proto,type,arg_ptr,&arg_sz) ==
- SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(sock_getopt(desc->s,proto,type,
+ arg_ptr,&arg_sz))) {
TRUNCATE_TO(0,ptr);
continue;
}
@@ -5645,7 +5661,7 @@ static int inet_fill_opts(inet_descriptor* desc,
RETURN_ERROR();
}
/* We have 5 bytes allocated to ptr */
- if (sock_getopt(desc->s,proto,type,arg_ptr,&arg_sz) == SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(sock_getopt(desc->s,proto,type,arg_ptr,&arg_sz))) {
TRUNCATE_TO(0,ptr);
continue;
}
@@ -6711,7 +6727,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len,
if (len != 0)
return ctl_error(EINVAL, rbuf, rsize);
- if (sock_hostname(tbuf, MAXHOSTNAMELEN) == SOCKET_ERROR)
+ if (IS_SOCKET_ERROR(sock_hostname(tbuf, MAXHOSTNAMELEN)))
return ctl_error(sock_errno(), rbuf, rsize);
return ctl_reply(INET_REP_OK, tbuf, strlen(tbuf), rbuf, rsize);
}
@@ -6728,7 +6744,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len,
return ctl_error(ENOTCONN, rbuf, rsize);
if ((ptr = desc->peer_ptr) == NULL) {
ptr = &peer;
- if (sock_peer(desc->s, (struct sockaddr*)ptr,&sz) == SOCKET_ERROR)
+ if (IS_SOCKET_ERROR(sock_peer(desc->s, (struct sockaddr*)ptr,&sz)))
return ctl_error(sock_errno(), rbuf, rsize);
}
if (inet_get_address(desc->sfamily, tbuf, ptr, &sz) < 0)
@@ -6765,7 +6781,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len,
if ((ptr = desc->name_ptr) == NULL) {
ptr = &name;
- if (sock_name(desc->s, (struct sockaddr*)ptr, &sz) == SOCKET_ERROR)
+ if (IS_SOCKET_ERROR(sock_name(desc->s, (struct sockaddr*)ptr, &sz)))
return ctl_error(sock_errno(), rbuf, rsize);
}
if (inet_get_address(desc->sfamily, tbuf, ptr, &sz) < 0)
@@ -6804,7 +6820,7 @@ static int inet_ctl(inet_descriptor* desc, int cmd, char* buf, int len,
if (inet_set_address(desc->sfamily, &local, buf, &len) == NULL)
return ctl_error(EINVAL, rbuf, rsize);
- if (sock_bind(desc->s,(struct sockaddr*) &local, len) == SOCKET_ERROR)
+ if (IS_SOCKET_ERROR(sock_bind(desc->s,(struct sockaddr*) &local, len)))
return ctl_error(sock_errno(), rbuf, rsize);
desc->state = INET_STATE_BOUND;
@@ -7237,7 +7253,7 @@ static int tcp_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, int len,
if (len != 2)
return ctl_error(EINVAL, rbuf, rsize);
backlog = get_int16(buf);
- if (sock_listen(desc->inet.s, backlog) == SOCKET_ERROR)
+ if (IS_SOCKET_ERROR(sock_listen(desc->inet.s, backlog)))
return ctl_error(sock_errno(), rbuf, rsize);
desc->inet.state = TCP_STATE_LISTEN;
return ctl_reply(INET_REP_OK, NULL, 0, rbuf, rsize);
@@ -7271,7 +7287,7 @@ static int tcp_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, int len,
code = sock_connect(desc->inet.s,
(struct sockaddr*) &desc->inet.remote, len);
- if ((code == SOCKET_ERROR) &&
+ if (IS_SOCKET_ERROR(code) &&
((sock_errno() == ERRNO_BLOCK) || /* Winsock2 */
(sock_errno() == EINPROGRESS))) { /* Unix & OSE!! */
sock_select(INETP(desc), FD_CONNECT, 1);
@@ -7947,7 +7963,7 @@ static int tcp_recv(tcp_descriptor* desc, int request_len)
n = sock_recv(desc->inet.s, desc->i_ptr, nread, 0);
- if (n == SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(n)) {
int err = sock_errno();
if (err == ECONNRESET) {
DEBUGF((" => detected close (connreset)\r\n"));
@@ -8449,8 +8465,8 @@ static int tcp_sendv(tcp_descriptor* desc, ErlIOVec* ev)
(long)desc->inet.port, desc->inet.s, h_len, len));
if (desc->tcp_add_flags & TCP_ADDF_DELAY_SEND) {
n = 0;
- } else if (sock_sendv(desc->inet.s, ev->iov, vsize, &n, 0)
- == SOCKET_ERROR) {
+ } else if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s, ev->iov,
+ vsize, &n, 0))) {
if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) {
int err = sock_errno();
DEBUGF(("tcp_sendv(%ld): s=%d, "
@@ -8543,7 +8559,7 @@ static int tcp_send(tcp_descriptor* desc, char* ptr, int len)
if (desc->tcp_add_flags & TCP_ADDF_DELAY_SEND) {
sock_send(desc->inet.s, buf, 0, 0);
n = 0;
- } else if (sock_sendv(desc->inet.s,iov,2,&n,0) == SOCKET_ERROR) {
+ } else if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s,iov,2,&n,0))) {
if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) {
int err = sock_errno();
DEBUGF(("tcp_send(%ld): s=%d,sock_sendv(size=2) errno = %d\r\n",
@@ -8616,7 +8632,7 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
int code = sock_peer(desc->inet.s,
(struct sockaddr*) &desc->inet.remote, &sz);
- if (code == SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(code)) {
desc->inet.state = TCP_STATE_BOUND; /* restore state */
ret = async_error(INETP(desc), sock_errno());
goto done;
@@ -8657,7 +8673,7 @@ static int tcp_inet_output(tcp_descriptor* desc, HANDLE event)
vsize = vsize > MAX_VSIZE ? MAX_VSIZE : vsize;
DEBUGF(("tcp_inet_output(%ld): s=%d, About to send %d items\r\n",
(long)desc->inet.port, desc->inet.s, vsize));
- if (sock_sendv(desc->inet.s, iov, vsize, &n, 0)==SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(sock_sendv(desc->inet.s, iov, vsize, &n, 0))) {
if ((sock_errno() != ERRNO_BLOCK) && (sock_errno() != EINTR)) {
DEBUGF(("tcp_inet_output(%ld): sock_sendv(%d) errno = %d\r\n",
(long)desc->inet.port, vsize, sock_errno()));
@@ -8926,7 +8942,7 @@ static int packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, int len,
sock_select(desc, FD_CONNECT, 1);
code = sock_connect(desc->s, &remote.sa, len);
- if ((code == SOCKET_ERROR) && (sock_errno() == EINPROGRESS)) {
+ if (IS_SOCKET_ERROR(code) && (sock_errno() == EINPROGRESS)) {
/* XXX: Unix only -- WinSock would have a different cond! */
desc->state = SCTP_STATE_CONNECTING;
if (timeout != INET_INFINITY)
@@ -8966,7 +8982,7 @@ static int packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, int len,
code = sock_connect(desc->s,
(struct sockaddr*) &desc->remote, len);
- if (code == SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(code)) {
sock_connect(desc->s, (struct sockaddr*) NULL, 0);
desc->state &= ~INET_F_ACTIVE;
return ctl_error(sock_errno(), rbuf, rsize);
@@ -9000,7 +9016,7 @@ static int packet_inet_ctl(ErlDrvData e, unsigned int cmd, char* buf, int len,
return ctl_error(EINVAL, rbuf, rsize);
flag = get_int8(buf);
- if (sock_listen(desc->s, flag) == SOCKET_ERROR)
+ if (IS_SOCKET_ERROR(sock_listen(desc->s, flag)))
return ctl_error(sock_errno(), rbuf, rsize);
desc->state = SCTP_STATE_LISTEN; /* XXX: not used? */
@@ -9205,7 +9221,7 @@ static void packet_inet_command(ErlDrvData e, char* buf, int len)
check_result_code:
/* "code" analysis is the same for both SCTP and UDP cases above: */
#endif
- if (code == SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(code)) {
int err = sock_errno();
inet_reply_error(desc, err);
}
@@ -9304,7 +9320,7 @@ static int packet_inet_input(udp_descriptor* udesc, HANDLE event)
check_result:
#endif
/* Analyse the result: */
- if (n == SOCKET_ERROR
+ if (IS_SOCKET_ERROR(n)
#ifdef HAVE_SCTP
|| (short_recv = (IS_SCTP(desc) && !(mhdr.msg_flags & MSG_EOR)))
/* NB: here we check for EOR not being set -- this is an error as
@@ -9419,7 +9435,7 @@ static int packet_inet_output(udp_descriptor* udesc, HANDLE event)
int code = sock_peer(desc->s,
(struct sockaddr*) &desc->remote, &sz);
- if (code == SOCKET_ERROR) {
+ if (IS_SOCKET_ERROR(code)) {
desc->state = PACKET_STATE_BOUND; /* restore state */
ret = async_error(desc, sock_errno());
goto done;
@@ -9860,23 +9876,26 @@ int erts_sock_connect(erts_sock_t socket, byte *ip_addr, int len, Uint16 port)
if (!inet_set_address(AF_INET, &addr, buf, &blen))
return 0;
- if (SOCKET_ERROR == sock_connect(s,
+ if (IS_SOCKET_ERROR(sock_connect(s,
(struct sockaddr *) &addr,
- sizeof(struct sockaddr_in)))
+ sizeof(struct sockaddr_in))))
return 0;
return 1;
}
Sint erts_sock_send(erts_sock_t socket, const void *buf, Sint len)
{
- return (Sint) sock_send((SOCKET) socket, buf, (size_t) len, 0);
+ Sint result = (Sint) sock_send((SOCKET) socket, buf, (size_t) len, 0);
+ if (IS_SOCKET_ERROR(result))
+ return SOCKET_ERROR;
+ return result;
}
int erts_sock_gethostname(char *buf, int bufsz)
{
- if (sock_hostname(buf, bufsz) == SOCKET_ERROR)
- return -1;
+ if (IS_SOCKET_ERROR(sock_hostname(buf, bufsz)))
+ return SOCKET_ERROR;
return 0;
}
diff --git a/erts/emulator/drivers/common/ram_file_drv.c b/erts/emulator/drivers/common/ram_file_drv.c
index 4a39a156e6..abedcc933a 100644
--- a/erts/emulator/drivers/common/ram_file_drv.c
+++ b/erts/emulator/drivers/common/ram_file_drv.c
@@ -35,6 +35,7 @@
#define RAM_FILE_TRUNCATE 14
#define RAM_FILE_PREAD 17
#define RAM_FILE_PWRITE 18
+#define RAM_FILE_FDATASYNC 19
/* other operations */
#define RAM_FILE_GET 30
@@ -45,6 +46,8 @@
#define RAM_FILE_UUENCODE 35 /* uuencode file */
#define RAM_FILE_UUDECODE 36 /* uudecode file */
#define RAM_FILE_SIZE 37 /* get file size */
+#define RAM_FILE_ADVISE 38 /* predeclare the access
+ * pattern for file data */
/* possible new operations include:
DES_ENCRYPT
DES_DECRYPT
@@ -558,6 +561,13 @@ static void rfile_command(ErlDrvData e, char* buf, int count)
numeric_reply(f, 0); /* 0 is not used */
break;
+ case RAM_FILE_FDATASYNC:
+ if (f->flags == 0)
+ error_reply(f, EBADF);
+ else
+ reply(f, 1, 0);
+ break;
+
case RAM_FILE_FSYNC:
if (f->flags == 0)
error_reply(f, EBADF);
@@ -685,6 +695,13 @@ static void rfile_command(ErlDrvData e, char* buf, int count)
case RAM_FILE_UUDECODE: /* uudecode file */
ram_file_uudecode(f);
break;
+
+ case RAM_FILE_ADVISE:
+ if (f->flags == 0)
+ error_reply(f, EBADF);
+ else
+ reply(f, 1, 0);
+ break;
}
/*
* Ignore anything else -- let the caller hang.
diff --git a/erts/emulator/drivers/unix/unix_efile.c b/erts/emulator/drivers/unix/unix_efile.c
index 1d094ee613..ea016526ef 100644
--- a/erts/emulator/drivers/unix/unix_efile.c
+++ b/erts/emulator/drivers/unix/unix_efile.c
@@ -774,6 +774,17 @@ efile_closefile(int fd)
}
int
+efile_fdatasync(Efile_error *errInfo, /* Where to return error codes. */
+ int fd) /* File descriptor for file to sync data. */
+{
+#ifdef HAVE_FDATASYNC
+ return check_error(fdatasync(fd), errInfo);
+#else
+ return efile_fsync(errInfo, fd);
+#endif
+}
+
+int
efile_fsync(Efile_error *errInfo, /* Where to return error codes. */
int fd) /* File descriptor for file to sync. */
{
@@ -1437,3 +1448,14 @@ efile_symlink(Efile_error* errInfo, char* old, char* new)
return check_error(symlink(old, new), errInfo);
#endif
}
+
+int
+efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset,
+ Sint64 length, int advise)
+{
+#ifdef HAVE_POSIX_FADVISE
+ return check_error(posix_fadvise(fd, offset, length, advise), errInfo);
+#else
+ return check_error(0, errInfo);
+#endif
+}
diff --git a/erts/emulator/drivers/win32/win_efile.c b/erts/emulator/drivers/win32/win_efile.c
index 89aaad31da..24b6fb30dc 100644
--- a/erts/emulator/drivers/win32/win_efile.c
+++ b/erts/emulator/drivers/win32/win_efile.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%
*/
/*
@@ -689,7 +689,8 @@ Sint64* pSize; /* Where to store the size of the file. */
if (flags & EFILE_MODE_APPEND) {
crFlags = OPEN_ALWAYS;
}
- fd = CreateFile(name, access, FILE_SHARE_READ | FILE_SHARE_WRITE,
+ fd = CreateFile(name, access,
+ FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, crFlags, FILE_ATTRIBUTE_NORMAL, NULL);
/*
@@ -764,6 +765,15 @@ int fd; /* File descriptor for file to close. */
}
int
+efile_fdatasync(errInfo, fd)
+Efile_error* errInfo; /* Where to return error codes. */
+int fd; /* File descriptor for file to sync. */
+{
+ /* Not available in Windows, just call regular fsync */
+ return efile_fsync(errInfo, fd);
+}
+
+int
efile_fsync(errInfo, fd)
Efile_error* errInfo; /* Where to return error codes. */
int fd; /* File descriptor for file to sync. */
@@ -1424,3 +1434,12 @@ efile_symlink(Efile_error* errInfo, char* old, char* new)
errno = ENOTSUP;
return check_error(-1, errInfo);
}
+
+int
+efile_fadvise(Efile_error* errInfo, int fd, Sint64 offset,
+ Sint64 length, int advise)
+{
+ /* posix_fadvise is not available on Windows, do nothing */
+ errno = ERROR_SUCCESS;
+ return check_error(0, errInfo);
+}
diff --git a/erts/emulator/hipe/hipe_gc.c b/erts/emulator/hipe/hipe_gc.c
index e57e293547..6c9e1d9ba7 100644
--- a/erts/emulator/hipe/hipe_gc.c
+++ b/erts/emulator/hipe/hipe_gc.c
@@ -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%
*/
/* $Id$
@@ -86,7 +86,7 @@ Eterm *fullsweep_nstack(Process *p, Eterm *n_htop)
if (is_boxed(gval)) {
Eterm *ptr = boxed_val(gval);
Eterm val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*nsp_i = val;
} else if (in_area(ptr, src, src_size) ||
@@ -96,7 +96,7 @@ Eterm *fullsweep_nstack(Process *p, Eterm *n_htop)
} else if (is_list(gval)) {
Eterm *ptr = list_val(gval);
Eterm val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
*nsp_i = ptr[1];
} else if (in_area(ptr, src, src_size) ||
in_area(ptr, oh, oh_size)) {
@@ -193,7 +193,7 @@ void gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop)
if (is_boxed(gval)) {
Eterm *ptr = boxed_val(gval);
Eterm val = *ptr;
- if (IS_MOVED(val)) {
+ if (IS_MOVED_BOXED(val)) {
ASSERT(is_boxed(val));
*nsp_i = val;
} else if (in_area(ptr, heap, mature_size)) {
@@ -205,7 +205,7 @@ void gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop)
} else if (is_list(gval)) {
Eterm *ptr = list_val(gval);
Eterm val = *ptr;
- if (is_non_value(val)) {
+ if (IS_MOVED_CONS(val)) {
*nsp_i = ptr[1];
} else if (in_area(ptr, heap, mature_size)) {
MOVE_CONS(ptr, val, old_htop, nsp_i);
diff --git a/erts/emulator/sys/common/erl_poll.c b/erts/emulator/sys/common/erl_poll.c
index 5cca33d7eb..09fb6337f7 100644
--- a/erts/emulator/sys/common/erl_poll.c
+++ b/erts/emulator/sys/common/erl_poll.c
@@ -130,13 +130,18 @@
#define ERTS_POLLSET_IS_POLLED(PS) \
((int) erts_smp_atomic_read(&(PS)->polled))
-#define ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) \
- ((int) erts_smp_atomic_xchg(&(PS)->woken, (long) 1))
-#define ERTS_POLLSET_SET_POLLER_WOKEN(PS) \
- erts_smp_atomic_set(&(PS)->woken, (long) 1)
-#define ERTS_POLLSET_UNSET_POLLER_WOKEN(PS) \
- erts_smp_atomic_set(&(PS)->woken, (long) 0)
-#define ERTS_POLLSET_IS_POLLER_WOKEN(PS) \
+#define ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) set_poller_woken_chk((PS))
+#define ERTS_POLLSET_SET_POLLER_WOKEN(PS) \
+do { \
+ ERTS_THR_MEMORY_BARRIER; \
+ erts_smp_atomic_set(&(PS)->woken, (long) 1); \
+} while (0)
+#define ERTS_POLLSET_UNSET_POLLER_WOKEN(PS) \
+do { \
+ erts_smp_atomic_set(&(PS)->woken, (long) 0); \
+ ERTS_THR_MEMORY_BARRIER; \
+} while (0)
+#define ERTS_POLLSET_IS_POLLER_WOKEN(PS) \
((int) erts_smp_atomic_read(&(PS)->woken))
#else
@@ -194,13 +199,18 @@
#else
-#define ERTS_POLLSET_UNSET_INTERRUPTED_CHK(PS) \
- ((int) erts_smp_atomic_xchg(&(PS)->interrupt, (long) 0))
-#define ERTS_POLLSET_UNSET_INTERRUPTED(PS) \
- erts_smp_atomic_set(&(PS)->interrupt, (long) 0)
-#define ERTS_POLLSET_SET_INTERRUPTED(PS) \
- erts_smp_atomic_set(&(PS)->interrupt, (long) 1)
-#define ERTS_POLLSET_IS_INTERRUPTED(PS) \
+#define ERTS_POLLSET_UNSET_INTERRUPTED_CHK(PS) unset_interrupted_chk((PS))
+#define ERTS_POLLSET_UNSET_INTERRUPTED(PS) \
+do { \
+ erts_smp_atomic_set(&(PS)->interrupt, (long) 0); \
+ ERTS_THR_MEMORY_BARRIER; \
+} while (0)
+#define ERTS_POLLSET_SET_INTERRUPTED(PS) \
+do { \
+ ERTS_THR_MEMORY_BARRIER; \
+ erts_smp_atomic_set(&(PS)->interrupt, (long) 1); \
+} while (0)
+#define ERTS_POLLSET_IS_INTERRUPTED(PS) \
((int) erts_smp_atomic_read(&(PS)->interrupt))
#endif
@@ -336,16 +346,30 @@ struct ErtsPollSet_ {
#endif
};
-#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT && !defined(ERTS_SMP)
-
static ERTS_INLINE int
unset_interrupted_chk(ErtsPollSet ps)
{
+ int res;
+#if ERTS_POLL_ASYNC_INTERRUPT_SUPPORT && !defined(ERTS_SMP)
/* This operation isn't atomic, but we have no need at all for an
atomic operation here... */
- int res = ps->interrupt;
+ res = ps->interrupt;
ps->interrupt = 0;
+#else
+ res = (int) erts_smp_atomic_xchg(&ps->interrupt, (long) 0);
+ ERTS_THR_MEMORY_BARRIER;
+#endif
return res;
+
+}
+
+#ifdef ERTS_SMP
+
+static ERTS_INLINE int
+set_poller_woken_chk(ErtsPollSet ps)
+{
+ ERTS_THR_MEMORY_BARRIER;
+ return (int) erts_smp_atomic_xchg(&ps->woken, (long) 1);
}
#endif
@@ -2405,6 +2429,7 @@ ERTS_POLL_EXPORT(erts_poll_info)(ErtsPollSet ps, ErtsPollInfo *pip)
while (urqbp) {
size += sizeof(ErtsPollSetUpdateRequestsBlock);
pending_updates += urqbp->len;
+ urqbp = urqbp->next;
}
}
#endif
diff --git a/erts/emulator/sys/unix/erl9_start.c b/erts/emulator/sys/unix/erl9_start.c
deleted file mode 100644
index 578062d7e2..0000000000
--- a/erts/emulator/sys/unix/erl9_start.c
+++ /dev/null
@@ -1,130 +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%
- */
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-#include "sys.h"
-#include "erl_vm.h"
-#include "global.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/*
- * XXX This is a temporary dummy to make sys.c happy until we'll rewrite it.
- */
-unsigned preloaded_size_ring0 = 1;
-unsigned char preloaded_ring0[1] = {0};
-
-Preload pre_loaded[] = {
- {"ring0", 1, preloaded_ring0},
- {0, 0, 0}
-};
-
-int
-main(int argc, char** argv)
-{
- char sbuf[1024];
- struct {
- void* p;
- int sz;
- } bins[2];
- int bin_num = 0;
- FILE* fp;
- char* progname = argv[0];
- char* eq;
-
- argv++, argc--;
-
- if (argc > 0 && argv[0][0] == '-') {
- argv++, argc--;
- }
- if (argc < 1) {
- abort();
- }
- if ((fp = fopen(argv[0], "r")) == NULL) {
- abort();
- }
-
- /* Needs to be called before any memory allocation */
- erts_short_init();
-
- while (fgets(sbuf, sizeof sbuf, fp)) {
- if (sbuf[0] == '#') {
- continue; /* Comment */
- } else if (sbuf[0] == 'e' && strncmp("exec", sbuf, 4) == 0) {
- continue; /* Comment ;-) */
- } else if ((eq = strchr(sbuf, '=')) != NULL) {
- char* val;
- char* p = strchr(sbuf, '\n');
- if (p) {
- *p = '\0';
- }
- *eq = '\0';
- val = erts_read_env(sbuf);
- if (val == NULL) {
- *eq = '=';
- erts_sys_putenv(sbuf, eq - &sbuf[0]);
- }
- erts_free_read_env(val);
- } else if (sbuf[0] == ':' && '0' <= sbuf[1] && sbuf[1] <= '9') {
- int load_size = atoi(sbuf+1);
- void* bin;
-
- bin = malloc(load_size);
- if (fread(bin, 1, load_size, fp) != load_size) {
- abort();
- }
- bins[bin_num].p = bin;
- bins[bin_num].sz = load_size;
- bin_num++;
- } else if (strcmp(sbuf, "--end--\n") == 0) {
- int rval;
- Eterm mod = NIL;
- char *val;
-
- fclose(fp);
-
- if (bin_num != 2) {
- abort();
- }
-
- val = erts_read_env("ERLBREAKHANDLER");
- if (val) {
- init_break_handler();
- }
- erts_free_read_env(val);
-
- if ((rval = erts_load_module(NULL, 0, NIL, &mod, bins[0].p, bins[0].sz)) < 0) {
- fprintf(stderr, "%s: Load of initial module failed: %d\n",
- progname, rval);
- abort();
- }
- erts_first_process(mod, bins[1].p, bins[1].sz, argc, argv);
- free(bins[0].p);
- free(bins[1].p);
- process_main();
- abort();
- } else {
- fprintf(stderr, "%s: bad line: %s\n", progname, sbuf);
- abort();
- }
- }
- abort();
-}
diff --git a/erts/emulator/sys/win32/erl_poll.c b/erts/emulator/sys/win32/erl_poll.c
index d816cc2c07..a766fe9575 100644
--- a/erts/emulator/sys/win32/erl_poll.c
+++ b/erts/emulator/sys/win32/erl_poll.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%
*/
#ifdef HAVE_CONFIG_H
@@ -304,24 +304,51 @@ struct ErtsPollSet_ {
erts_smp_atomic_set(&(PS)->polled, (long) 0)
#define ERTS_POLLSET_IS_POLLED(PS) \
((int) erts_smp_atomic_read(&(PS)->polled))
-#define ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) \
- ((int) erts_smp_atomic_xchg(&(PS)->woken, (long) 1))
-#define ERTS_POLLSET_SET_POLLER_WOKEN(PS) \
- erts_smp_atomic_set(&(PS)->woken, (long) 1)
-#define ERTS_POLLSET_UNSET_POLLER_WOKEN(PS) \
- erts_smp_atomic_set(&(PS)->woken, (long) 0)
-#define ERTS_POLLSET_IS_POLLER_WOKEN(PS) \
+
+#define ERTS_POLLSET_SET_POLLER_WOKEN_CHK(PS) set_poller_woken_chk((PS))
+#define ERTS_POLLSET_SET_POLLER_WOKEN(PS) \
+do { \
+ ERTS_THR_MEMORY_BARRIER; \
+ erts_smp_atomic_set(&(PS)->woken, (long) 1); \
+} while (0)
+#define ERTS_POLLSET_UNSET_POLLER_WOKEN(PS) \
+do { \
+ erts_smp_atomic_set(&(PS)->woken, (long) 0); \
+ ERTS_THR_MEMORY_BARRIER; \
+} while (0)
+#define ERTS_POLLSET_IS_POLLER_WOKEN(PS) \
((int) erts_smp_atomic_read(&(PS)->woken))
-#define ERTS_POLLSET_UNSET_INTERRUPTED_CHK(PS) \
- ((int) erts_smp_atomic_xchg(&(PS)->interrupt, (long) 0))
-#define ERTS_POLLSET_UNSET_INTERRUPTED(PS) \
- erts_smp_atomic_set(&(PS)->interrupt, (long) 0)
-#define ERTS_POLLSET_SET_INTERRUPTED(PS) \
- erts_smp_atomic_set(&(PS)->interrupt, (long) 1)
-#define ERTS_POLLSET_IS_INTERRUPTED(PS) \
+#define ERTS_POLLSET_UNSET_INTERRUPTED_CHK(PS) unset_interrupted_chk((PS))
+#define ERTS_POLLSET_UNSET_INTERRUPTED(PS) \
+do { \
+ erts_smp_atomic_set(&(PS)->interrupt, (long) 0); \
+ ERTS_THR_MEMORY_BARRIER; \
+} while (0)
+#define ERTS_POLLSET_SET_INTERRUPTED(PS) \
+do { \
+ ERTS_THR_MEMORY_BARRIER; \
+ erts_smp_atomic_set(&(PS)->interrupt, (long) 1); \
+} while (0)
+#define ERTS_POLLSET_IS_INTERRUPTED(PS) \
((int) erts_smp_atomic_read(&(PS)->interrupt))
+static ERTS_INLINE int
+unset_interrupted_chk(ErtsPollSet ps)
+{
+ int res = (int) erts_smp_atomic_xchg(&ps->interrupt, (long) 0);
+ ERTS_THR_MEMORY_BARRIER;
+ return res;
+
+}
+
+static ERTS_INLINE int
+set_poller_woken_chk(ErtsPollSet ps)
+{
+ ERTS_THR_MEMORY_BARRIER;
+ return (int) erts_smp_atomic_xchg(&ps->woken, (long) 1);
+}
+
#else
#define ERTS_POLLSET_LOCK(PS)
diff --git a/erts/emulator/sys/win32/sys.c b/erts/emulator/sys/win32/sys.c
index 46dee826f0..d3921a14f8 100644
--- a/erts/emulator/sys/win32/sys.c
+++ b/erts/emulator/sys/win32/sys.c
@@ -33,6 +33,7 @@
#include "../../drivers/win32/win_con.h"
+
void erts_sys_init_float(void);
void erl_start(int, char**);
@@ -95,6 +96,10 @@ static erts_smp_mtx_t sys_driver_data_lock;
static FUNCTION(int, driver_write, (long, HANDLE, byte*, int));
static void common_stop(int);
static int create_file_thread(struct async_io* aio, int mode);
+#ifdef ERTS_SMP
+static void close_active_handles(ErlDrvPort, const HANDLE* handles, int cnt);
+static DWORD WINAPI threaded_handle_closer(LPVOID param);
+#endif
static DWORD WINAPI threaded_reader(LPVOID param);
static DWORD WINAPI threaded_writer(LPVOID param);
static DWORD WINAPI threaded_exiter(LPVOID param);
@@ -132,6 +137,9 @@ static BOOL win_console = FALSE;
static OSVERSIONINFO int_os_version; /* Version information for Win32. */
+#ifdef ERTS_SMP
+static BOOL (WINAPI *fpCancelIoEx)(HANDLE,LPOVERLAPPED);
+#endif
/* This is the system's main function (which may or may not be called "main")
- do general system-dependent initialization
@@ -676,25 +684,50 @@ release_driver_data(DriverData* dp)
erts_smp_mtx_lock(&sys_driver_data_lock);
#ifdef ERTS_SMP
- /* This is a workaround for the fact that CancelIo cant cancel
- requests issued by another thread and that we still cant use
- CancelIoEx as that's only availabele in Vista etc. */
- if(dp->in.async_io_active && dp->in.fd != INVALID_HANDLE_VALUE) {
- CloseHandle(dp->in.fd);
- dp->in.fd = INVALID_HANDLE_VALUE;
- DEBUGF(("Waiting for the in event thingie"));
- WaitForSingleObject(dp->in.ov.hEvent,INFINITE);
- DEBUGF(("...done\n"));
- }
- if(dp->out.async_io_active && dp->out.fd != INVALID_HANDLE_VALUE) {
- CloseHandle(dp->out.fd);
- dp->out.fd = INVALID_HANDLE_VALUE;
- DEBUGF(("Waiting for the out event thingie"));
- WaitForSingleObject(dp->out.ov.hEvent,INFINITE);
- DEBUGF(("...done\n"));
+ if (fpCancelIoEx != NULL) {
+ if (dp->in.thread == (HANDLE) -1 && dp->in.fd != INVALID_HANDLE_VALUE) {
+ (*fpCancelIoEx)(dp->in.fd, NULL);
+ }
+ if (dp->out.thread == (HANDLE) -1 && dp->out.fd != INVALID_HANDLE_VALUE) {
+ (*fpCancelIoEx)(dp->out.fd, NULL);
+ }
+ }
+ else {
+ /* This is a workaround for the fact that CancelIo cant cancel
+ requests issued by another thread and that we cant use
+ CancelIoEx as that's only availabele in Vista etc.
+ R14: Avoid scheduler deadlock by only wait for 10ms, and then spawn
+ a thread that will keep waiting in in order to close handles. */
+ HANDLE handles[2];
+ int i = 0;
+ int timeout = 10;
+ if(dp->in.async_io_active && dp->in.fd != INVALID_HANDLE_VALUE) {
+ CloseHandle(dp->in.fd);
+ dp->in.fd = INVALID_HANDLE_VALUE;
+ DEBUGF(("Waiting for the in event thingie"));
+ if (WaitForSingleObject(dp->in.ov.hEvent,timeout) == WAIT_TIMEOUT) {
+ handles[i++] = dp->in.ov.hEvent;
+ dp->in.ov.hEvent = NULL;
+ timeout = 0;
+ }
+ DEBUGF(("...done\n"));
+ }
+ if(dp->out.async_io_active && dp->out.fd != INVALID_HANDLE_VALUE) {
+ CloseHandle(dp->out.fd);
+ dp->out.fd = INVALID_HANDLE_VALUE;
+ DEBUGF(("Waiting for the out event thingie"));
+ if (WaitForSingleObject(dp->out.ov.hEvent,timeout) == WAIT_TIMEOUT) {
+ handles[i++] = dp->out.ov.hEvent;
+ dp->out.ov.hEvent = NULL;
+ }
+ DEBUGF(("...done\n"));
+ }
+ if (i > 0) {
+ close_active_handles(dp->port_num, handles, i);
+ }
}
#else
- if (dp->out.thread == (HANDLE) -1 && dp->in.fd != INVALID_HANDLE_VALUE) {
+ if (dp->in.thread == (HANDLE) -1 && dp->in.fd != INVALID_HANDLE_VALUE) {
CancelIo(dp->in.fd);
}
if (dp->out.thread == (HANDLE) -1 && dp->out.fd != INVALID_HANDLE_VALUE) {
@@ -737,6 +770,48 @@ release_driver_data(DriverData* dp)
erts_smp_mtx_unlock(&sys_driver_data_lock);
}
+#ifdef ERTS_SMP
+
+struct handles_to_be_closed
+{
+ int cnt;
+ HANDLE handles[2];
+};
+
+static void close_active_handles(ErlDrvPort port_num, const HANDLE* handles, int cnt)
+{
+ DWORD tid;
+ HANDLE thread;
+ int i;
+ struct handles_to_be_closed* htbc = erts_alloc(ERTS_ALC_T_DRV_TAB,
+ sizeof(struct handles_to_be_closed));
+ htbc->cnt = cnt;
+ for (i=0; i < cnt; ++i) {
+ htbc->handles[i] = handles[i];
+ (void) driver_select(port_num, (ErlDrvEvent)handles[i],
+ ERL_DRV_USE_NO_CALLBACK, 0);
+ }
+ thread = (HANDLE *) _beginthreadex(NULL, 0, threaded_handle_closer, htbc, 0, &tid);
+ CloseHandle(thread);
+}
+
+
+static DWORD WINAPI
+threaded_handle_closer(LPVOID param)
+{
+ struct handles_to_be_closed* htbc = (struct handles_to_be_closed*) param;
+ int i;
+ DEBUGF(("threaded_handle_closer waiting for %d handles\r\n",htbc->cnt));
+ WaitForMultipleObjects(htbc->cnt, htbc->handles, TRUE, INFINITE);
+ for (i=0; i < htbc->cnt; ++i) {
+ CloseHandle(htbc->handles[i]);
+ }
+ erts_free(ERTS_ALC_T_DRV_TAB, htbc);
+ DEBUGF(("threaded_handle_closer terminating\r\n"));
+ return 0;
+}
+#endif /* ERTS_SMP */
+
/*
* Stores input and output file descriptors in the DriverData structure,
* and calls driver_select().
@@ -1026,12 +1101,19 @@ static int
spawn_init()
{
int i;
-
+#ifdef ERTS_SMP
+ HMODULE module = GetModuleHandle("kernel32");
+ fpCancelIoEx = (module != NULL) ?
+ (BOOL (WINAPI *)(HANDLE,LPOVERLAPPED))
+ GetProcAddress(module,"CancelIoEx") : NULL;
+ DEBUGF(("fpCancelIoEx = %p\r\n", fpCancelIoEx));
+#endif
driver_data = (struct driver_data *)
erts_alloc(ERTS_ALC_T_DRV_TAB, max_files * sizeof(struct driver_data));
erts_smp_atomic_add(&sys_misc_mem_sz, max_files*sizeof(struct driver_data));
for (i = 0; i < max_files; i++)
driver_data[i].port_num = PORT_FREE;
+
return 0;
}
@@ -2928,12 +3010,6 @@ erts_sys_pre_init(void)
erts_sys_env_init();
}
-/*
- * the last two only used for standalone erlang
- * they should are used by sae_main in beam dll to
- * enable standalone execution via erl_api-routines
- */
-
void noinherit_std_handle(DWORD type)
{
HANDLE h = GetStdHandle(type);
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index df2faf1450..97b94c466f 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -81,6 +81,7 @@ MODULES= \
port_bif_SUITE \
process_SUITE \
pseudoknot_SUITE \
+ receive_SUITE \
ref_SUITE \
register_SUITE \
save_calls_SUITE \
@@ -117,7 +118,8 @@ NO_OPT= bs_bincomp \
bs_match_int \
bs_match_tail \
bs_match_misc \
- bs_utf
+ bs_utf \
+ guard
NO_OPT_MODULES= $(NO_OPT:%=%_no_opt_SUITE)
diff --git a/erts/emulator/test/bif_SUITE.erl b/erts/emulator/test/bif_SUITE.erl
index cfbc5dfe81..15c09d9158 100644
--- a/erts/emulator/test/bif_SUITE.erl
+++ b/erts/emulator/test/bif_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%
%%
@@ -308,6 +308,18 @@ min_max(Config) when is_list(Config) ->
?line 42.0 = erlang:min(42.0, 42),
?line 42.0 = erlang:max(42.0, 42),
+ %% And now (R14) they are also autoimported!
+ ?line a = min(id(a), a),
+ ?line a = min(id(a), b),
+ ?line a = min(id(b), a),
+ ?line b = min(id(b), b),
+ ?line a = max(id(a), a),
+ ?line b = max(id(a), b),
+ ?line b = max(id(b), a),
+ ?line b = max(id(b), b),
+
+ ?line 42.0 = min(42.0, 42),
+ ?line 42.0 = max(42.0, 42),
ok.
diff --git a/erts/emulator/test/binary_SUITE.erl b/erts/emulator/test/binary_SUITE.erl
index 7ecc31aa29..77d2579848 100644
--- a/erts/emulator/test/binary_SUITE.erl
+++ b/erts/emulator/test/binary_SUITE.erl
@@ -438,11 +438,11 @@ terms(Config) when is_list(Config) ->
ok
end,
Term = binary_to_term(Bin),
- Term = erlang:binary_to_term(Bin, [safe]),
+ Term = 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]),
+ Term = binary_to_term(Unaligned, []),
+ Term = binary_to_term(Bin, [safe]),
BinC = erlang:term_to_binary(Term, [compressed]),
Term = binary_to_term(BinC),
true = size(BinC) =< size(Bin),
@@ -542,7 +542,7 @@ 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)).
+ {'EXIT',{badarg,_}} = (catch 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) ->
@@ -553,7 +553,7 @@ safe_binary_to_term2(Config) when is_list(Config) ->
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
+ ?line fullsweep_after = 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.
diff --git a/erts/emulator/test/busy_port_SUITE.erl b/erts/emulator/test/busy_port_SUITE.erl
index 9b16170293..7350aef4ec 100644
--- a/erts/emulator/test/busy_port_SUITE.erl
+++ b/erts/emulator/test/busy_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%
%%
@@ -182,7 +182,7 @@ system_monitor(Config) when is_list(Config) ->
?line Master ! {Owner, {command, "u"}},
?line {Busy,beta} = rec(Void),
?line Void = rec(Void),
- ?line NewMonitor = erlang:system_monitor(OldMonitor),
+ ?line _NewMonitor = erlang:system_monitor(OldMonitor),
?line OldMonitor = erlang:system_monitor(),
?line OldMonitor = erlang:system_monitor(OldMonitor),
%%
@@ -361,7 +361,6 @@ soft_busy_driver(Config) when is_list(Config) ->
hs_test(Config, false).
hs_test(Config, HardBusy) when is_list(Config) ->
- ?line Me = self(),
?line DrvName = case HardBusy of
true -> 'hard_busy_drv';
false -> 'soft_busy_drv'
@@ -479,7 +478,7 @@ hs_busy_pcmd(Prt, Opts, StartFun, EndFun) ->
Tester ! {self(), doing_port_command},
Start = os:timestamp(),
Res = try {return,
- erlang:port_command(Prt, [], Opts)}
+ port_command(Prt, [], Opts)}
catch Exception:Error -> {Exception, Error}
end,
End = os:timestamp(),
diff --git a/erts/emulator/test/distribution_SUITE.erl b/erts/emulator/test/distribution_SUITE.erl
index 8f48d8a992..7c19274696 100644
--- a/erts/emulator/test/distribution_SUITE.erl
+++ b/erts/emulator/test/distribution_SUITE.erl
@@ -1,23 +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%
%%
-module(distribution_SUITE).
+-compile(r12).
%% Tests distribution and the tcp driver.
diff --git a/erts/emulator/test/fun_r12_SUITE.erl b/erts/emulator/test/fun_r12_SUITE.erl
index f21299ba67..9262731dcb 100644
--- a/erts/emulator/test/fun_r12_SUITE.erl
+++ b/erts/emulator/test/fun_r12_SUITE.erl
@@ -18,6 +18,7 @@
%%
-module(fun_r12_SUITE).
+-compile(r12).
-export([all/1,init_per_testcase/2,fin_per_testcase/2,dist_old_release/1]).
diff --git a/erts/emulator/test/guard_SUITE.erl b/erts/emulator/test/guard_SUITE.erl
index 23482a20d7..8fef36dfaf 100644
--- a/erts/emulator/test/guard_SUITE.erl
+++ b/erts/emulator/test/guard_SUITE.erl
@@ -1,33 +1,34 @@
%%
%% %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(guard_SUITE).
-export([all/1, bad_arith/1, bad_tuple/1, test_heap_guards/1, guard_bifs/1,
- type_tests/1]).
+ type_tests/1,guard_bif_binary_part/1]).
-include("test_server.hrl").
-export([init/3]).
-import(lists, [member/2]).
-all(suite) -> [bad_arith, bad_tuple, test_heap_guards, guard_bifs, type_tests].
+all(suite) -> [bad_arith, bad_tuple, test_heap_guards, guard_bifs,
+ type_tests, guard_bif_binary_part].
bad_arith(doc) -> "Test that a bad arithmetic operation in a guard works correctly.";
bad_arith(Config) when is_list(Config) ->
@@ -136,6 +137,170 @@ init(Fun, Args, Filler) ->
dummy(_) ->
ok.
+-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))).
+mask_error({'EXIT',{Err,_}}) ->
+ Err;
+mask_error(Else) ->
+ Else.
+
+guard_bif_binary_part(doc) ->
+ ["Test the binary_part/2,3 guard BIF's extensively"];
+guard_bif_binary_part(Config) when is_list(Config) ->
+ %% Overflow tests that need to be unoptimized
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF,
+ -16#7FFFFFFFFFFFFFFF-1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF,
+ 16#7FFFFFFFFFFFFFFF})),
+ F = fun(X) ->
+ Master = self(),
+ {Pid,Ref} = spawn_monitor( fun() ->
+ A = lists:duplicate(X,a),
+ B = [do_binary_part_guard() | A],
+ Master ! {self(),hd(B)},
+ ok
+ end),
+ receive
+ {Pid,ok} ->
+ erlang:demonitor(Ref,[flush]),
+ ok;
+ Error ->
+ Error
+ end
+ end,
+ [ ok = F(N) || N <- lists:seq(1,10000) ],
+ ok.
+
+
+do_binary_part_guard() ->
+ ?line 1 = bptest(<<1,2,3>>),
+ ?line 2 = bptest(<<2,1,3>>),
+ ?line error = bptest(<<1>>),
+ ?line error = bptest(<<>>),
+ ?line error = bptest(apa),
+ ?line 3 = bptest(<<2,3,3>>),
+ % With one variable (pos)
+ ?line 1 = bptest(<<1,2,3>>,1),
+ ?line 2 = bptest(<<2,1,3>>,1),
+ ?line error = bptest(<<1>>,1),
+ ?line error = bptest(<<>>,1),
+ ?line error = bptest(apa,1),
+ ?line 3 = bptest(<<2,3,3>>,1),
+ % With one variable (length)
+ ?line 1 = bptesty(<<1,2,3>>,1),
+ ?line 2 = bptesty(<<2,1,3>>,1),
+ ?line error = bptesty(<<1>>,1),
+ ?line error = bptesty(<<>>,1),
+ ?line error = bptesty(apa,1),
+ ?line 3 = bptesty(<<2,3,3>>,2),
+ % With one variable (whole tuple)
+ ?line 1 = bptestx(<<1,2,3>>,{1,1}),
+ ?line 2 = bptestx(<<2,1,3>>,{1,1}),
+ ?line error = bptestx(<<1>>,{1,1}),
+ ?line error = bptestx(<<>>,{1,1}),
+ ?line error = bptestx(apa,{1,1}),
+ ?line 3 = bptestx(<<2,3,3>>,{1,2}),
+ % With two variables
+ ?line 1 = bptest(<<1,2,3>>,1,1),
+ ?line 2 = bptest(<<2,1,3>>,1,1),
+ ?line error = bptest(<<1>>,1,1),
+ ?line error = bptest(<<>>,1,1),
+ ?line error = bptest(apa,1,1),
+ ?line 3 = bptest(<<2,3,3>>,1,2),
+ % Direct (autoimported) call, these will be evaluated by the compiler...
+ ?line <<2>> = binary_part(<<1,2,3>>,1,1),
+ ?line <<1>> = binary_part(<<2,1,3>>,1,1),
+ % Compiler warnings due to constant evaluation expected (3)
+ ?line badarg = ?MASK_ERROR(binary_part(<<1>>,1,1)),
+ ?line badarg = ?MASK_ERROR(binary_part(<<>>,1,1)),
+ ?line badarg = ?MASK_ERROR(binary_part(apa,1,1)),
+ ?line <<3,3>> = binary_part(<<2,3,3>>,1,2),
+ % Direct call through apply
+ ?line <<2>> = apply(erlang,binary_part,[<<1,2,3>>,1,1]),
+ ?line <<1>> = apply(erlang,binary_part,[<<2,1,3>>,1,1]),
+ % Compiler warnings due to constant evaluation expected (3)
+ ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<1>>,1,1])),
+ ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<>>,1,1])),
+ ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[apa,1,1])),
+ ?line <<3,3>> = apply(erlang,binary_part,[<<2,3,3>>,1,2]),
+ % Constant propagation
+ ?line Bin = <<1,2,3>>,
+ ?line ok = if
+ binary_part(Bin,1,1) =:= <<2>> ->
+ ok;
+ %% Compiler warning, clause cannot match (expected)
+ true ->
+ error
+ end,
+ ?line ok = if
+ binary_part(Bin,{1,1}) =:= <<2>> ->
+ ok;
+ %% Compiler warning, clause cannot match (expected)
+ true ->
+ error
+ end,
+ ok.
+
+
+bptest(B) when length(B) =:= 1337 ->
+ 1;
+bptest(B) when binary_part(B,{1,1}) =:= <<2>> ->
+ 1;
+bptest(B) when erlang:binary_part(B,1,1) =:= <<1>> ->
+ 2;
+bptest(B) when erlang:binary_part(B,{1,2}) =:= <<3,3>> ->
+ 3;
+bptest(_) ->
+ error.
+
+bptest(B,A) when length(B) =:= A ->
+ 1;
+bptest(B,A) when binary_part(B,{A,1}) =:= <<2>> ->
+ 1;
+bptest(B,A) when erlang:binary_part(B,A,1) =:= <<1>> ->
+ 2;
+bptest(B,A) when erlang:binary_part(B,{A,2}) =:= <<3,3>> ->
+ 3;
+bptest(_,_) ->
+ error.
+
+bptestx(B,A) when length(B) =:= A ->
+ 1;
+bptestx(B,A) when binary_part(B,A) =:= <<2>> ->
+ 1;
+bptestx(B,A) when erlang:binary_part(B,A) =:= <<1>> ->
+ 2;
+bptestx(B,A) when erlang:binary_part(B,A) =:= <<3,3>> ->
+ 3;
+bptestx(_,_) ->
+ error.
+
+bptesty(B,A) when length(B) =:= A ->
+ 1;
+bptesty(B,A) when binary_part(B,{1,A}) =:= <<2>> ->
+ 1;
+bptesty(B,A) when erlang:binary_part(B,1,A) =:= <<1>> ->
+ 2;
+bptesty(B,A) when erlang:binary_part(B,{1,A}) =:= <<3,3>> ->
+ 3;
+bptesty(_,_) ->
+ error.
+
+bptest(B,A,_C) when length(B) =:= A ->
+ 1;
+bptest(B,A,C) when binary_part(B,{A,C}) =:= <<2>> ->
+ 1;
+bptest(B,A,C) when erlang:binary_part(B,A,C) =:= <<1>> ->
+ 2;
+bptest(B,A,C) when erlang:binary_part(B,{A,C}) =:= <<3,3>> ->
+ 3;
+bptest(_,_,_) ->
+ error.
+
+
guard_bifs(doc) -> "Test all guard bifs with nasty (but legal arguments).";
guard_bifs(Config) when is_list(Config) ->
?line Big = -237849247829874297658726487367328971246284736473821617265433,
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index 522caec8f1..a1f61dad67 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -20,23 +20,39 @@
-module(nif_SUITE).
%%-define(line_trace,true).
-%%-define(CHECK(Exp,Got), ?line check(Exp,Got,?LINE)).
--define(CHECK(Exp,Got), ?line Exp = Got).
+-define(CHECK(Exp,Got), 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,
+-export([all/1,
+ %%init_per_testcase/2,
+ fin_per_testcase/2, basic/1, reload/1, upgrade/1, heap_frag/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]).
+ from_array/1, iolist_as_binary/1, resource/1, resource_binary/1, resource_takeover/1,
+ threading/1, send/1, send2/1, send_threaded/1, neg/1, is_checks/1,
+ get_length/1, make_atom/1, make_string/1]).
-export([many_args_100/100]).
+
+
+%% -export([lib_version/0,call_history/0,hold_nif_mod_priv_data/1,nif_mod_call_history/0,
+%% list_seq/1,type_test/0,tuple_2_list/1,is_identical/2,compare/2,
+%% clone_bin/1,make_sub_bin/3,string_to_bin/2,atom_to_bin/2,macros/1,
+%% tuple_2_list_and_tuple/1,iolist_2_bin/1,get_resource_type/1,alloc_resource/2,
+%% make_resource/1,get_resource/2,release_resource/1,last_resource_dtor_call/0,
+%% make_new_resource/2,make_new_resource_binary/1,send_list_seq/2,send_new_blob/2,
+%% alloc_msgenv/0,clear_msgenv/1,grow_blob/2,send_blob/2,send_blob_thread/3,
+%% join_send_thread/1]).
+
+
-define(nif_stub,nif_stub_error(?LINE)).
all(suite) ->
[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].
+ get_atom, api_macros, from_array, iolist_as_binary, resource, resource_binary,
+ resource_takeover, threading, send, send2, send_threaded, neg, is_checks,
+ get_length, make_atom, make_string].
%%init_per_testcase(_Case, Config) ->
%% ?line Dog = ?t:timetrap(?t:seconds(60*60*24)),
@@ -473,12 +489,51 @@ resource_new_do2(Type) ->
{{PtrA,BinA}, {ResB,PtrB,BinB}}.
resource_neg(TypeA) ->
+ resource_neg_do(TypeA),
+
+ catch exit(42), % dummy exception to purge saved stacktraces from earlier exception
+ erlang:garbage_collect(),
+ ?line {_,_,2} = last_resource_dtor_call(),
+ ok.
+
+resource_neg_do(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)),
+ ResA = make_new_resource(TypeA, <<"Arnold">>),
+ ResB= make_new_resource(TypeB, <<"Bobo">>),
+ ?line {'EXIT',{badarg,_}} = (catch get_resource(TypeA, ResB)),
+ ?line {'EXIT',{badarg,_}} = (catch get_resource(TypeB, ResA)),
+ ok.
+
+resource_binary(doc) -> ["Test enif_make_resource_binary"];
+resource_binary(suite) -> [];
+resource_binary(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line {Ptr,Bin} = resource_binary_do(),
+ erlang:garbage_collect(),
+ Last = last_resource_dtor_call(),
+ ?CHECK({Ptr,Bin,1}, Last),
ok.
+
+resource_binary_do() ->
+ Bin = <<"Hej Hopp i lingonskogen">>,
+ ?line {Ptr,ResBin1} = make_new_resource_binary(Bin),
+ ?line ResBin1 = Bin,
+ ?line ResInfo = {Ptr,_} = get_resource(binary_resource_type,ResBin1),
+
+ Papa = self(),
+ Forwarder = spawn_link(fun() -> forwarder(Papa) end),
+ io:format("sending to forwarder pid=~p\n",[Forwarder]),
+ Forwarder ! ResBin1,
+ ResBin2 = receive_any(),
+ ?line ResBin2 = ResBin1,
+ ?line ResInfo = get_resource(binary_resource_type,ResBin2),
+ Forwarder ! terminate,
+ ?line {Forwarder, 1} = receive_any(),
+ erlang:garbage_collect(),
+ ?line ResInfo = get_resource(binary_resource_type,ResBin1),
+ ?line ResInfo = get_resource(binary_resource_type,ResBin2),
+ ResInfo.
+
-define(RT_CREATE,1).
-define(RT_TAKEOVER,2).
@@ -743,6 +798,124 @@ threading(Config) when is_list(Config) ->
?line ok = tester:load_nif_lib(Config, "tsd"),
?line ok = tester:run().
+
+send(doc) -> ["Test NIF message sending"];
+send(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+
+ N = 1500,
+ List = lists:seq(1,N),
+ ?line {ok,1} = send_list_seq(N, self),
+ ?line {ok,1} = send_list_seq(N, self()),
+ ?line List = receive_any(),
+ ?line List = receive_any(),
+ Papa = self(),
+ spawn_link(fun() -> ?line {ok,1} = send_list_seq(N, Papa) end),
+ ?line List = receive_any(),
+
+ ?line {ok, 1, BlobS} = send_new_blob(self(), other_term()),
+ ?line BlobR = receive_any(),
+ io:format("Sent ~p\nGot ~p\n", [BlobS, BlobR]),
+ ?line BlobR = BlobS,
+
+ %% send to dead pid
+ {DeadPid, DeadMon} = spawn_monitor(fun() -> void end),
+ ?line {'DOWN', DeadMon, process, DeadPid, normal} = receive_any(),
+ {ok,0} = send_list_seq(7, DeadPid),
+ ok.
+
+send2(doc) -> ["More NIF message sending"];
+send2(Config) when is_list(Config) ->
+ ensure_lib_loaded(Config),
+
+ send2_do1(fun send_blob_dbg/2),
+ ok.
+
+send_threaded(doc) -> ["Send msg from user thread"];
+send_threaded(Config) when is_list(Config) ->
+ case erlang:system_info(smp_support) of
+ true ->
+ send2_do1(fun(ME,To) -> send_blob_thread_dbg(ME,To,join) end),
+ send2_do1(fun(ME,To) -> send_blob_thread_and_join(ME,To) end),
+ ok;
+ false ->
+ {skipped,"No threaded send on non-SMP"}
+ end.
+
+
+send2_do1(SendBlobF) ->
+ io:format("sending to self=~p\n",[self()]),
+ send2_do2(SendBlobF, self()),
+
+ Papa = self(),
+ Forwarder = spawn_link(fun() -> forwarder(Papa) end),
+ io:format("sending to forwarder pid=~p\n",[Forwarder]),
+ send2_do2(SendBlobF, Forwarder),
+ Forwarder ! terminate,
+ ?line {Forwarder, 4} = receive_any(),
+ ok.
+
+send2_do2(SendBlobF, To) ->
+ MsgEnv = alloc_msgenv(),
+ repeat(50, fun(_) -> grow_blob(MsgEnv,other_term()) end, []),
+ ?line {ok,1,Blob0} = SendBlobF(MsgEnv, To),
+ ?line Blob1 = receive_any(),
+ ?line Blob1 = Blob0,
+
+ clear_msgenv(MsgEnv),
+ repeat(50, fun(_) -> grow_blob(MsgEnv,other_term()) end, []),
+ ?line {ok,1,Blob2} = SendBlobF(MsgEnv, To),
+ ?line Blob3 = receive_any(),
+ ?line Blob3 = Blob2,
+
+ clear_msgenv(MsgEnv),
+ repeat(50, fun(_) -> grow_blob(MsgEnv,other_term()) end, []),
+
+ clear_msgenv(MsgEnv),
+ repeat(50, fun(_) -> grow_blob(MsgEnv,other_term()) end, []),
+ ?line {ok,1,Blob4} = SendBlobF(MsgEnv, To),
+ ?line Blob5 = receive_any(),
+ ?line Blob5 = Blob4,
+
+ clear_msgenv(MsgEnv),
+ clear_msgenv(MsgEnv),
+ repeat(50, fun(_) -> grow_blob(MsgEnv,other_term()) end, []),
+ ?line {ok,1,Blob6} = SendBlobF(MsgEnv, To),
+ ?line Blob7 = receive_any(),
+ ?line Blob7 = Blob6,
+
+ ok.
+
+
+send_blob_thread_and_join(MsgEnv, To) ->
+ ?line {ok,Blob} = send_blob_thread_dbg(MsgEnv, To, no_join),
+ ?line {ok,SendRes} = join_send_thread(MsgEnv),
+ {ok,SendRes,Blob}.
+
+send_blob_dbg(MsgEnv, To) ->
+ Ret = send_blob(MsgEnv, To),
+ %%io:format("send_blob to ~p returned ~p\n",[To,Ret]),
+ Ret.
+
+send_blob_thread_dbg(MsgEnv, To, Join) ->
+ Ret = send_blob_thread(MsgEnv, To, Join),
+ %%io:format("send_blob_thread to ~p Join=~p returned ~p\n",[To,Join,Ret]),
+ Ret.
+
+
+forwarder(To) ->
+ forwarder(To, 0).
+forwarder(To, N) ->
+ case receive_any() of
+ terminate ->
+ To ! {self(), N};
+ Msg ->
+ To ! Msg,
+ forwarder(To, N+1)
+ end.
+
+other_term() ->
+ {fun(X,Y) -> X*Y end, make_ref()}.
neg(doc) -> ["Negative testing of load_nif"];
neg(Config) when is_list(Config) ->
@@ -759,7 +932,17 @@ neg(Config) when is_list(Config) ->
?line verify_tmpmem(TmpMem),
?line ok.
+is_checks(doc) -> ["Test all enif_is functions"];
+is_checks(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line ok = check_is(hejsan, <<19,98>>, make_ref(), ok, fun() -> ok end,
+ self(), hd(erlang:ports()), [], [1,9,9,8],
+ {hejsan, "hejsan", [$h,"ejs",<<"an">>]}).
+get_length(doc) -> ["Test all enif_get_length functions"];
+get_length(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line ok = length_test(hejsan, "hejsan", [], [], not_a_list).
ensure_lib_loaded(Config) ->
ensure_lib_loaded(Config, 1).
@@ -773,6 +956,22 @@ ensure_lib_loaded(Config, Ver) ->
ok
end.
+make_atom(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ An0Atom = an0atom,
+ An0Atom0 = 'an\000atom\000',
+ ?line Atoms = make_atoms(),
+ ?line 7 = size(Atoms),
+ ?line Atoms = {An0Atom,An0Atom,An0Atom,An0Atom0,An0Atom,An0Atom,An0Atom0}.
+
+make_string(Config) when is_list(Config) ->
+ ?line ensure_lib_loaded(Config, 1),
+ ?line Strings = make_strings(),
+ ?line 4 = size(Strings),
+ A0String = "a0string",
+ A0String0 = [$a,0,$s,$t,$r,$i,$n,$g,0],
+ ?line Strings = {A0String,A0String,A0String,A0String0}.
+
tmpmem() ->
case erlang:system_info({allocator,temp_alloc}) of
false -> undefined;
@@ -821,13 +1020,18 @@ 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.
+repeat(0, _, Arg) ->
+ Arg;
+repeat(N, Fun, Arg0) ->
+ repeat(N-1, Fun, Fun(Arg0)).
+
+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:
@@ -855,6 +1059,20 @@ get_resource(_,_) -> ?nif_stub.
release_resource(_) -> ?nif_stub.
last_resource_dtor_call() -> ?nif_stub.
make_new_resource(_,_) -> ?nif_stub.
+check_is(_,_,_,_,_,_,_,_,_,_) -> ?nif_stub.
+length_test(_,_,_,_,_) -> ?nif_stub.
+make_atoms() -> ?nif_stub.
+make_strings() -> ?nif_stub.
+make_new_resource_binary(_) -> ?nif_stub.
+send_list_seq(_,_) -> ?nif_stub.
+send_new_blob(_,_) -> ?nif_stub.
+alloc_msgenv() -> ?nif_stub.
+clear_msgenv(_) -> ?nif_stub.
+grow_blob(_,_) -> ?nif_stub.
+send_blob(_,_) -> ?nif_stub.
+send_blob_thread(_,_,_) -> ?nif_stub.
+join_send_thread(_) -> ?nif_stub.
+
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).
diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
index 3ad4f93374..bacf7845e2 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c
@@ -28,6 +28,12 @@
static int static_cntA; /* zero by default */
static int static_cntB = NIF_SUITE_LIB_VER * 100;
+static ERL_NIF_TERM atom_self;
+static ERL_NIF_TERM atom_ok;
+static ERL_NIF_TERM atom_join;
+static ERL_NIF_TERM atom_binary_resource_type;
+
+
typedef struct
{
int ref_cnt;
@@ -38,7 +44,7 @@ typedef struct
void add_call(ErlNifEnv* env, PrivData* data, const char* func_name)
{
- CallInfo* call = enif_alloc(env, sizeof(CallInfo)+strlen(func_name));
+ CallInfo* call = enif_alloc(sizeof(CallInfo)+strlen(func_name));
strcpy(call->func_name, func_name);
call->lib_ver = NIF_SUITE_LIB_VER;
call->next = data->call_history;
@@ -49,7 +55,7 @@ void add_call(ErlNifEnv* env, PrivData* data, const char* func_name)
call->arg_sz = 0;
}
-#define ADD_CALL(FUNC_NAME) add_call(env, enif_get_data(env),FUNC_NAME)
+#define ADD_CALL(FUNC_NAME) add_call(env, enif_priv_data(env),FUNC_NAME)
static void* resource_dtor_last = NULL;
static unsigned resource_dtor_last_sz = 0;
@@ -60,15 +66,24 @@ static void resource_dtor(ErlNifEnv* env, void* obj)
{
resource_dtor_last = obj;
resource_dtor_cnt++;
- resource_dtor_last_sz = enif_sizeof_resource(env, obj);
+ resource_dtor_last_sz = enif_sizeof_resource(obj);
assert(resource_dtor_last_sz <= sizeof(resource_dtor_last_data));
memcpy(resource_dtor_last_data, obj, resource_dtor_last_sz);
}
+static ErlNifResourceType* msgenv_resource_type;
+static void msgenv_dtor(ErlNifEnv* env, void* obj);
+
+static ErlNifResourceType* binary_resource_type;
+static void binary_resource_dtor(ErlNifEnv* env, void* obj);
+struct binary_resource {
+ unsigned char* data;
+ unsigned size;
+};
+
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));
+ PrivData* data = enif_alloc(sizeof(PrivData));
assert(data != NULL);
data->ref_cnt = 1;
data->call_history = NULL;
@@ -76,41 +91,71 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
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,
+ data->rt_arr[0].t = enif_open_resource_type(env,NULL,"Gold",resource_dtor,
ERL_NIF_RT_CREATE,NULL);
- data->rt_arr[1].t = enif_open_resource_type(env,"Silver",resource_dtor,
+ data->rt_arr[1].t = enif_open_resource_type(env,NULL,"Silver",resource_dtor,
ERL_NIF_RT_CREATE,NULL);
+ binary_resource_type = enif_open_resource_type(env,NULL,"nif_SUITE.binary",
+ binary_resource_dtor,
+ ERL_NIF_RT_CREATE, NULL);
+
+ msgenv_resource_type = enif_open_resource_type(env,NULL,"nif_SUITE.msgenv",
+ msgenv_dtor,
+ ERL_NIF_RT_CREATE, NULL);
+
+ atom_self = enif_make_atom(env,"self");
+ atom_ok = enif_make_atom(env,"ok");
+ atom_join = enif_make_atom(env,"join");
+ atom_binary_resource_type = enif_make_atom(env,"binary_resource_type");
+
*priv_data = data;
return 0;
}
+static void resource_takeover(ErlNifEnv* env, PrivData* priv)
+{
+ ErlNifResourceFlags tried;
+ ErlNifResourceType* rt;
+ rt = enif_open_resource_type(env, NULL, "Gold", resource_dtor,
+ ERL_NIF_RT_TAKEOVER, &tried);
+ assert(rt == priv->rt_arr[0].t);
+ assert(tried == ERL_NIF_RT_TAKEOVER);
+ rt = enif_open_resource_type(env, NULL, "Silver", resource_dtor,
+ ERL_NIF_RT_TAKEOVER, &tried);
+ assert(rt == priv->rt_arr[1].t);
+ assert(tried == ERL_NIF_RT_TAKEOVER);
+
+ rt = enif_open_resource_type(env, NULL, "nif_SUITE.binary", binary_resource_dtor,
+ ERL_NIF_RT_TAKEOVER, &tried);
+ assert(rt != NULL);
+ assert(tried == ERL_NIF_RT_TAKEOVER);
+ assert(binary_resource_type==NULL || binary_resource_type == rt);
+ binary_resource_type = rt;
+
+ rt = enif_open_resource_type(env, NULL, "nif_SUITE.msgenv", msgenv_dtor,
+ ERL_NIF_RT_TAKEOVER, &tried);
+ assert(rt != NULL);
+ assert(tried == ERL_NIF_RT_TAKEOVER);
+ assert(msgenv_resource_type==NULL || msgenv_resource_type == rt);
+ msgenv_resource_type = rt;
+}
+
static int reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
{
- add_call(env, *priv_data, "reload");
+ PrivData* priv = (PrivData*) *priv_data;
+ add_call(env, priv, "reload");
+ resource_takeover(env,priv);
return 0;
}
static int upgrade(ErlNifEnv* env, void** priv_data, void** old_priv_data, ERL_NIF_TERM load_info)
{
- PrivData* data = *old_priv_data;
- add_call(env, data, "upgrade");
- data->ref_cnt++;
- *priv_data = *old_priv_data;
+ PrivData* priv = (PrivData*) *old_priv_data;
+ add_call(env, priv, "upgrade");
+ priv->ref_cnt++;
+ *priv_data = *old_priv_data;
+ resource_takeover(env,priv);
return 0;
}
@@ -119,7 +164,10 @@ static void unload(ErlNifEnv* env, void* priv_data)
PrivData* data = priv_data;
add_call(env, data, "unload");
if (--data->ref_cnt == 0) {
- enif_free(env, priv_data);
+ if (data->nif_mod != NULL) {
+ NifModPrivData_release(data->nif_mod);
+ }
+ enif_free(priv_data);
}
}
@@ -149,28 +197,28 @@ static ERL_NIF_TERM make_call_history(ErlNifEnv* env, CallInfo** headp)
enif_make_int(env,call->static_cntB));
list = enif_make_list_cell(env, tpl, list);
*headp = call->next;
- enif_free(env,call);
+ enif_free(call);
}
return list;
}
static ERL_NIF_TERM call_history(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- PrivData* data = (PrivData*) enif_get_data(env);
+ PrivData* data = (PrivData*) enif_priv_data(env);
return make_call_history(env,&data->call_history);
}
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);
+ PrivData* data = (PrivData*) enif_priv_data(env);
unsigned long 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) {
- enif_free(env,data->nif_mod);
+ if (data->nif_mod != NULL) {
+ NifModPrivData_release(data->nif_mod);
}
data->nif_mod = (NifModPrivData*) ptr_as_ulong;
return enif_make_int(env,++(data->nif_mod->ref_cnt));
@@ -178,7 +226,7 @@ static ERL_NIF_TERM hold_nif_mod_priv_data(ErlNifEnv* env, int argc, const ERL_N
static ERL_NIF_TERM nif_mod_call_history(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- PrivData* data = (PrivData*) enif_get_data(env);
+ PrivData* data = (PrivData*) enif_priv_data(env);
ERL_NIF_TERM ret;
if (data->nif_mod == NULL) {
return enif_make_string(env,"nif_mod pointer is NULL", ERL_NIF_LATIN1);
@@ -354,13 +402,13 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
}
}
- if (!enif_make_existing_atom(env,"nif_SUITE", &atom)
- || !enif_is_identical(env,atom,enif_make_atom(env,"nif_SUITE"))) {
+ if (!enif_make_existing_atom(env,"nif_SUITE", &atom, ERL_NIF_LATIN1)
+ || !enif_is_identical(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)) {
+ if (enif_make_existing_atom(env,"nif_SUITE_pink_unicorn", &atom, ERL_NIF_LATIN1)) {
fprintf(stderr, "pink unicorn exist?\r\n");
goto error;
}
@@ -368,7 +416,7 @@ static ERL_NIF_TERM type_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
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) {
+ || enif_is_identical(ref1,ref2) || enif_compare(ref1,ref2)==0) {
fprintf(stderr, "strange refs?\r\n");
goto error;
}
@@ -398,7 +446,7 @@ static ERL_NIF_TERM is_identical(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
if (argc != 2) {
return enif_make_badarg(env);
}
- return enif_make_atom(env, (enif_is_identical(env,argv[0],argv[1]) ?
+ return enif_make_atom(env, (enif_is_identical(argv[0],argv[1]) ?
"true" : "false"));
}
@@ -407,7 +455,7 @@ 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]));
+ return enif_make_int(env, enif_compare(argv[0],argv[1]));
}
static ERL_NIF_TERM many_args_100(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -454,7 +502,7 @@ static ERL_NIF_TERM string_to_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM a
unsigned size;
int n;
if (!enif_get_int(env,argv[1],(int*)&size)
- || !enif_alloc_binary(env,size,&obin)) {
+ || !enif_alloc_binary(size,&obin)) {
return enif_make_badarg(env);
}
n = enif_get_string(env, argv[0], (char*)obin.data, size, ERL_NIF_LATIN1);
@@ -468,10 +516,10 @@ static ERL_NIF_TERM atom_to_bin(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
unsigned size;
int n;
if (!enif_get_int(env,argv[1],(int*)&size)
- || !enif_alloc_binary(env,size,&obin)) {
+ || !enif_alloc_binary(size,&obin)) {
return enif_make_badarg(env);
}
- n = enif_get_atom(env, argv[0], (char*)obin.data, size);
+ n = enif_get_atom(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));
}
@@ -552,7 +600,7 @@ static ERL_NIF_TERM last_resource_dtor_call(ErlNifEnv* env, int argc, const ERL_
static ERL_NIF_TERM get_resource_type(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- PrivData* data = (PrivData*) enif_get_data(env);
+ PrivData* data = (PrivData*) enif_priv_data(env);
int ix;
if (!enif_get_int(env, argv[0], &ix) || ix >= 2) {
@@ -568,7 +616,7 @@ static ERL_NIF_TERM alloc_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM
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) {
+ || (data.p = enif_alloc_resource(type.t, data_bin.size))==NULL) {
return enif_make_badarg(env);
}
@@ -593,28 +641,65 @@ static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TE
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) {
+ || (data = enif_alloc_resource(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);
+ enif_release_resource(data);
return ret;
}
+static ERL_NIF_TERM make_new_resource_binary(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifBinary data_bin;
+ union { struct binary_resource* p; void* vp; long l;} br;
+ void* buf;
+ ERL_NIF_TERM ret;
+ if (!enif_inspect_binary(env, argv[0], &data_bin)
+ || (br.vp = enif_alloc_resource(binary_resource_type,
+ sizeof(struct binary_resource)))==NULL
+ || (buf = enif_alloc(data_bin.size)) == NULL) {
+
+ return enif_make_badarg(env);
+ }
+ memset(br.vp,0xba,sizeof(struct binary_resource)); /* avoid valgrind warning */
+ br.p->data = buf;
+ br.p->size = data_bin.size;
+ memcpy(br.p->data, data_bin.data, data_bin.size);
+ ret = enif_make_resource_binary(env, br.vp, br.p->data, br.p->size);
+ enif_release_resource(br.p);
+ return enif_make_tuple2(env, enif_make_long(env,br.l), ret);
+}
+
+static void binary_resource_dtor(ErlNifEnv* env, void* obj)
+{
+ struct binary_resource* br = (struct binary_resource*) obj;
+ resource_dtor(env,obj);
+ assert(br->data != NULL);
+ enif_free(br->data);
+ br->data = NULL;
+}
+
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)
+ type.t = NULL;
+ if (enif_is_identical(argv[0], atom_binary_resource_type)) {
+ type.t = binary_resource_type;
+ }
+ else {
+ enif_get_long(env, argv[0], &type.l);
+ }
+ if (type.t == NULL
|| !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);
+ enif_alloc_binary(enif_sizeof_resource(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));
@@ -626,10 +711,546 @@ static ERL_NIF_TERM release_resource(ErlNifEnv* env, int argc, const ERL_NIF_TER
if (!enif_get_long(env, argv[0], &data.l)) {
return enif_make_badarg(env);
}
- enif_release_resource(env, data.p);
+ enif_release_resource(data.p);
return enif_make_atom(env,"ok");
}
+/*
+ * argv[0] an atom
+ * argv[1] a binary
+ * argv[2] a ref
+ * argv[3] 'ok'
+ * argv[4] a fun
+ * argv[5] a pid
+ * argv[6] a port
+ * argv[7] an empty list
+ * argv[8] a non-empty list
+ * argv[9] a tuple
+ */
+static ERL_NIF_TERM check_is(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ERL_NIF_TERM ok_atom = enif_make_atom(env, "ok");
+
+ if (!enif_is_atom(env, argv[0])) return enif_make_badarg(env);
+ if (!enif_is_binary(env, argv[1])) return enif_make_badarg(env);
+ if (!enif_is_ref(env, argv[2])) return enif_make_badarg(env);
+ if (!enif_is_identical(argv[3], ok_atom)) return enif_make_badarg(env);
+ if (!enif_is_fun(env, argv[4])) return enif_make_badarg(env);
+ if (!enif_is_pid(env, argv[5])) return enif_make_badarg(env);
+ if (!enif_is_port(env, argv[6])) return enif_make_badarg(env);
+ if (!enif_is_empty_list(env, argv[7])) return enif_make_badarg(env);
+ if (!enif_is_list(env, argv[7])) return enif_make_badarg(env);
+ if (!enif_is_list(env, argv[8])) return enif_make_badarg(env);
+ if (!enif_is_tuple(env, argv[9])) return enif_make_badarg(env);
+
+ return ok_atom;
+}
+
+/*
+ * argv[0] atom with length of 6
+ * argv[1] list with length of 6
+ * argv[2] empty list
+ * argv[3] not an atom
+ * argv[4] not a list
+ */
+static ERL_NIF_TERM length_test(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ unsigned len;
+
+ if (!enif_get_atom_length(env, argv[0], &len, ERL_NIF_LATIN1) || len != 6)
+ return enif_make_badarg(env);
+
+ if (!enif_get_list_length(env, argv[1], &len) || len != 6)
+ return enif_make_badarg(env);
+
+ if (!enif_get_list_length(env, argv[2], &len) || len != 0)
+ return enif_make_badarg(env);
+
+ if (enif_get_atom_length(env, argv[3], &len, ERL_NIF_LATIN1))
+ return enif_make_badarg(env);
+
+ if (enif_get_list_length(env, argv[4], &len))
+ return enif_make_badarg(env);
+
+ return enif_make_atom(env, "ok");
+}
+
+static ERL_NIF_TERM make_atoms(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ERL_NIF_TERM arr[7];
+ ERL_NIF_TERM existingatom0a, existingatom0b;
+ ERL_NIF_TERM existing0atom0;
+ const char * const an0atom = "an0atom";
+ const char an0atom0[8] = {'a','n','\0','a','t','o','m',0};
+
+ arr[0] = enif_make_atom(env, "an0atom");
+ arr[1] = enif_make_atom_len(env, "an0atom", 7);
+ arr[2] = enif_make_atom_len(env, an0atom, 7);
+ arr[3] = enif_make_atom_len(env, an0atom0, 8);
+
+ if (!enif_make_existing_atom(env, "an0atom", &existingatom0a, ERL_NIF_LATIN1))
+ return enif_make_atom(env, "error");
+ arr[4] = existingatom0a;
+
+ if (!enif_make_existing_atom_len(env, an0atom, 7, &existingatom0b, ERL_NIF_LATIN1))
+ return enif_make_atom(env, "error");
+ arr[5] = existingatom0b;
+
+ if (!enif_make_existing_atom_len(env, an0atom0, 8, &existing0atom0, ERL_NIF_LATIN1))
+ return enif_make_atom(env, "error");
+ arr[6] = existing0atom0;
+
+ return enif_make_tuple7(env,
+ arr[0],arr[1],arr[2],arr[3],arr[4],arr[5],arr[6]);
+}
+
+static ERL_NIF_TERM make_strings(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ const char a0string[8] = {'a','0','s','t','r','i','n','g'};
+ const char a0string0[9] = {'a','\0','s','t','r','i','n','g',0};
+
+ return enif_make_tuple4(env,
+ enif_make_string(env, "a0string", ERL_NIF_LATIN1),
+ enif_make_string_len(env, "a0string", 8, ERL_NIF_LATIN1),
+ enif_make_string_len(env, a0string, 8, ERL_NIF_LATIN1),
+ enif_make_string_len(env, a0string0, 9, ERL_NIF_LATIN1));
+}
+static ERL_NIF_TERM send_list_seq(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifPid to;
+ ERL_NIF_TERM msg;
+ ErlNifEnv* msg_env;
+ int i, res;
+
+ if (!enif_get_int(env, argv[0], &i)) {
+ return enif_make_badarg(env);
+ }
+ if (argv[1] == atom_self) {
+ enif_self(env, &to);
+ }
+ else if (!enif_get_local_pid(env, argv[1], &to)) {
+ return enif_make_badarg(env);
+ }
+ msg_env = enif_alloc_env();
+ msg = enif_make_list(msg_env,0);
+ for ( ; i>0 ; i--) {
+ msg = enif_make_list_cell(msg_env, enif_make_int(msg_env, i), msg);
+ }
+ res = enif_send(env, &to, msg_env, msg);
+ enif_free_env(msg_env);
+ return enif_make_tuple2(env, atom_ok, enif_make_int(env,res));
+}
+
+static void fill(void* dst, unsigned bytes, int seed)
+{
+ unsigned char* ptr = dst;
+ int i;
+ for (i=bytes; i>0; i--) {
+ *ptr++ = seed;
+ seed += 7;
+ }
+}
+
+#define MAKE_TERM_REUSE_LEN 16
+struct make_term_info
+{
+ ErlNifEnv* caller_env;
+ ErlNifEnv* dst_env;
+ ERL_NIF_TERM reuse[MAKE_TERM_REUSE_LEN];
+ unsigned reuse_push;
+ unsigned reuse_pull;
+ ErlNifResourceType* resource_type;
+ ERL_NIF_TERM other_term;
+ ERL_NIF_TERM blob;
+ ErlNifPid to_pid;
+ ErlNifTid tid;
+ ErlNifCond* cond;
+ ErlNifMutex* mtx;
+ int send_it;
+ int send_res;
+ unsigned n;
+};
+
+
+static void push_term(struct make_term_info* mti, ERL_NIF_TERM term)
+{
+ unsigned ix = (mti->reuse_push++) % MAKE_TERM_REUSE_LEN;
+ mti->reuse[ix] = term;
+ //enif_fprintf(stderr, "push at %u: %T\r\n", ix, term);
+}
+static ERL_NIF_TERM pull_term(struct make_term_info* mti)
+{
+ unsigned ix;
+ if (mti->reuse_pull >= mti->reuse_push &&
+ mti->reuse_push < MAKE_TERM_REUSE_LEN) {
+ mti->reuse_pull = 0;
+ if (mti->reuse_push == 0) {
+ mti->reuse[0] = enif_make_list(mti->dst_env, 0);
+ }
+ }
+ ix = (mti->reuse_pull++) % MAKE_TERM_REUSE_LEN;
+ //enif_fprintf(stderr, "pull from %u: %T\r\n", ix, mti->reuse[ix]);
+ return mti->reuse[ix];
+}
+
+static int make_term_n(struct make_term_info* mti, int n, ERL_NIF_TERM* res);
+
+static ERL_NIF_TERM make_term_binary(struct make_term_info* mti, int n)
+{
+ ErlNifBinary bin;
+ enif_alloc_binary(100, &bin);
+ fill(bin.data, bin.size, n);
+ return enif_make_binary(mti->dst_env, &bin);
+}
+
+static ERL_NIF_TERM make_term_int(struct make_term_info* mti, int n)
+{
+ int i;
+ fill(&i, sizeof(i), n);
+ return enif_make_int(mti->dst_env, i);
+}
+
+static ERL_NIF_TERM make_term_ulong(struct make_term_info* mti, int n)
+{
+ unsigned long ul;
+ fill(&ul, sizeof(ul), n);
+ return enif_make_ulong(mti->dst_env, ul);
+}
+
+static ERL_NIF_TERM make_term_double(struct make_term_info* mti, int n)
+{
+ double d = 3.141592;
+ return enif_make_double(mti->dst_env, d);
+}
+static ERL_NIF_TERM make_term_atom(struct make_term_info* mti, int n)
+{
+ return enif_make_atom(mti->dst_env, "make_term_n");
+}
+static ERL_NIF_TERM make_term_existing_atom(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM res;
+ int exist = enif_make_existing_atom(mti->dst_env, "nif_SUITE", &res,
+ ERL_NIF_LATIN1);
+ assert(exist);
+ return res;
+}
+static ERL_NIF_TERM make_term_string(struct make_term_info* mti, int n)
+{
+ return enif_make_string(mti->dst_env, "Hello!", ERL_NIF_LATIN1);
+}
+static ERL_NIF_TERM make_term_ref(struct make_term_info* mti, int n)
+{
+ return enif_make_ref(mti->dst_env);
+}
+static ERL_NIF_TERM make_term_sub_binary(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM orig;
+ unsigned char* ptr = enif_make_new_binary(mti->dst_env, 10, &orig);
+ fill(ptr, 10, n);
+ return enif_make_sub_binary(mti->dst_env, orig, 3, 5);
+}
+static ERL_NIF_TERM make_term_uint(struct make_term_info* mti, int n)
+{
+ unsigned int ui;
+ fill(&ui, sizeof(ui), n);
+ return enif_make_uint(mti->dst_env, ui);
+}
+static ERL_NIF_TERM make_term_long(struct make_term_info* mti, int n)
+{
+ long l;
+ fill(&l, sizeof(l), n);
+ return enif_make_long(mti->dst_env, l);
+}
+static ERL_NIF_TERM make_term_tuple0(struct make_term_info* mti, int n)
+{
+ return enif_make_tuple(mti->dst_env, 0);
+}
+static ERL_NIF_TERM make_term_list0(struct make_term_info* mti, int n)
+{
+ return enif_make_list(mti->dst_env, 0);
+}
+static ERL_NIF_TERM make_term_resource(struct make_term_info* mti, int n)
+{
+ void* resource = enif_alloc_resource(mti->resource_type, 10);
+ fill(resource, 10, n);
+ return enif_make_resource(mti->dst_env, resource);
+}
+static ERL_NIF_TERM make_term_new_binary(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM res;
+ unsigned char* ptr = enif_make_new_binary(mti->dst_env,20,&res);
+ fill(ptr, 20, n);
+ return res;
+}
+static ERL_NIF_TERM make_term_caller_pid(struct make_term_info* mti, int n)
+{
+ ErlNifPid pid;
+ return enif_make_pid(mti->dst_env, enif_self(mti->caller_env, &pid));
+}
+
+static ERL_NIF_TERM make_term_tuple(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM t[3];
+ t[0] = pull_term(mti);
+ t[1] = pull_term(mti);
+ t[2] = pull_term(mti);
+ return enif_make_tuple3(mti->dst_env, t[0], t[1], t[2]);
+}
+static ERL_NIF_TERM make_term_list(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM t[3];
+ t[0] = pull_term(mti);
+ t[1] = pull_term(mti);
+ t[2] = pull_term(mti);
+ return enif_make_list3(mti->dst_env, t[0], t[1], t[2]);
+}
+static ERL_NIF_TERM make_term_list_cell(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM t[2];
+ t[0] = pull_term(mti);
+ t[1] = pull_term(mti);
+ return enif_make_list_cell(mti->dst_env, t[0], t[1]);
+}
+static ERL_NIF_TERM make_term_tuple_from_array(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM t[3];
+ t[0] = pull_term(mti);
+ t[1] = pull_term(mti);
+ t[2] = pull_term(mti);
+ return enif_make_tuple_from_array(mti->dst_env, t, 3);
+}
+static ERL_NIF_TERM make_term_list_from_array(struct make_term_info* mti, int n)
+{
+ ERL_NIF_TERM t[3];
+ t[0] = pull_term(mti);
+ t[1] = pull_term(mti);
+ t[2] = pull_term(mti);
+ return enif_make_list_from_array(mti->dst_env, t, 3);
+}
+static ERL_NIF_TERM make_term_garbage(struct make_term_info* mti, int n)
+{
+ (void) enif_make_string(mti->dst_env, "garbage string", ERL_NIF_LATIN1);
+ return pull_term(mti);
+}
+static ERL_NIF_TERM make_term_copy(struct make_term_info* mti, int n)
+{
+ return enif_make_copy(mti->dst_env, mti->other_term);
+}
+static int make_term_n(struct make_term_info* mti, int n, ERL_NIF_TERM* res)
+{
+ typedef ERL_NIF_TERM Make_term_Func(struct make_term_info*, int);
+ static Make_term_Func* funcs[] = {
+ make_term_binary,
+ make_term_int,
+ make_term_ulong,
+ make_term_double,
+ make_term_atom,
+ make_term_existing_atom,
+ make_term_string,
+ //make_term_ref,
+ make_term_sub_binary,
+ make_term_uint,
+ make_term_long,
+ make_term_tuple0,
+ make_term_list0,
+ make_term_resource,
+ make_term_new_binary,
+ make_term_caller_pid,
+ make_term_tuple,
+ make_term_list,
+ make_term_list_cell,
+ make_term_tuple_from_array,
+ make_term_list_from_array,
+ make_term_garbage,
+ make_term_copy
+ };
+ if (n < sizeof(funcs)/sizeof(*funcs)) {
+ *res = funcs[n](mti, n);
+ push_term(mti, *res);
+ return 1;
+ }
+ return 0;
+}
+
+static ERL_NIF_TERM make_blob(ErlNifEnv* caller_env, ErlNifEnv* dst_env,
+ ERL_NIF_TERM other_term)
+{
+ PrivData* priv = (PrivData*) enif_priv_data(caller_env);
+ ERL_NIF_TERM term, list;
+ int n = 0;
+ struct make_term_info mti;
+ mti.caller_env = caller_env;
+ mti.dst_env = dst_env;
+ mti.reuse_push = 0;
+ mti.reuse_pull = 0;
+ mti.resource_type = priv->rt_arr[0].t;
+ mti.other_term = other_term;
+
+ list = enif_make_list(dst_env, 0);
+ while (make_term_n(&mti, n++, &term)) {
+ list = enif_make_list_cell(dst_env, term, list);
+ }
+ return list;
+}
+
+static ERL_NIF_TERM send_new_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ ErlNifPid to;
+ ERL_NIF_TERM msg, copy;
+ ErlNifEnv* msg_env;
+ int res;
+
+ if (!enif_get_local_pid(env, argv[0], &to)) {
+ return enif_make_badarg(env);
+ }
+ msg_env = enif_alloc_env();
+ msg = make_blob(env,msg_env, argv[1]);
+ copy = make_blob(env,env, argv[1]);
+ res = enif_send(env, &to, msg_env, msg);
+ enif_free_env(msg_env);
+ return enif_make_tuple3(env, atom_ok, enif_make_int(env,res), copy);
+}
+
+static ERL_NIF_TERM alloc_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ PrivData* priv = (PrivData*) enif_priv_data(env);
+ struct make_term_info* mti;
+ ERL_NIF_TERM ret;
+
+ mti = (struct make_term_info*) enif_alloc_resource(msgenv_resource_type,
+ sizeof(*mti));
+ mti->caller_env = NULL;
+ mti->dst_env = enif_alloc_env();
+ mti->reuse_push = 0;
+ mti->reuse_pull = 0;
+ mti->resource_type = priv->rt_arr[0].t;
+ mti->other_term = enif_make_list(mti->dst_env, 0);
+ mti->blob = enif_make_list(mti->dst_env, 0);
+ mti->mtx = enif_mutex_create("nif_SUITE:mtx");
+ mti->cond = enif_cond_create("nif_SUITE:cond");
+ mti->send_res = 0xcafebabe;
+ mti->n = 0;
+ ret = enif_make_resource(env, mti);
+ enif_release_resource(mti);
+ return ret;
+}
+
+static void msgenv_dtor(ErlNifEnv* env, void* obj)
+{
+ struct make_term_info* mti = (struct make_term_info*) obj;
+ if (mti->dst_env != NULL) {
+ enif_free_env(mti->dst_env);
+ }
+ enif_mutex_destroy(mti->mtx);
+ enif_cond_destroy(mti->cond);
+}
+
+static ERL_NIF_TERM clear_msgenv(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ union {
+ void* vp;
+ struct make_term_info* p;
+ }mti;
+ if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
+ return enif_make_badarg(env);
+ }
+ enif_clear_env(mti.p->dst_env);
+ mti.p->reuse_pull = 0;
+ mti.p->reuse_push = 0;
+ mti.p->blob = enif_make_list(mti.p->dst_env, 0);
+ return atom_ok;
+}
+
+static ERL_NIF_TERM grow_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ union { void* vp; struct make_term_info* p; }mti;
+ ERL_NIF_TERM term;
+ if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
+ return enif_make_badarg(env);
+ }
+ mti.p->caller_env = env;
+ mti.p->other_term = argv[1];
+ while (!make_term_n(mti.p, mti.p->n++, &term)) {
+ mti.p->n = 0;
+ }
+ mti.p->blob = enif_make_list_cell(mti.p->dst_env, term, mti.p->blob);
+ return atom_ok;
+}
+
+static ERL_NIF_TERM send_blob(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ union { void* vp; struct make_term_info* p; }mti;
+ ErlNifPid to;
+ ERL_NIF_TERM copy;
+ int res;
+ if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)
+ || !enif_get_local_pid(env, argv[1], &to)) {
+ return enif_make_badarg(env);
+ }
+ copy = enif_make_copy(env, mti.p->blob);
+ res = enif_send(env, &to, mti.p->dst_env, mti.p->blob);
+ return enif_make_tuple3(env, atom_ok, enif_make_int(env,res), copy);
+}
+
+void* threaded_sender(void *arg)
+{
+
+ union { void* vp; struct make_term_info* p; }mti;
+ mti.vp = arg;
+
+ enif_mutex_lock(mti.p->mtx);
+ while (!mti.p->send_it) {
+ enif_cond_wait(mti.p->cond, mti.p->mtx);
+ }
+ mti.p->send_it = 0;
+ enif_mutex_unlock(mti.p->mtx);
+ mti.p->send_res = enif_send(NULL, &mti.p->to_pid, mti.p->dst_env, mti.p->blob);
+ return NULL;
+}
+
+static ERL_NIF_TERM send_blob_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ union { void* vp; struct make_term_info* p; }mti;
+ ERL_NIF_TERM copy;
+ if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)
+ || !enif_get_local_pid(env,argv[1], &mti.p->to_pid)) {
+ return enif_make_badarg(env);
+ }
+ copy = enif_make_copy(env, mti.p->blob);
+
+ mti.p->send_it = enif_is_identical(argv[2],atom_join);
+ if (enif_thread_create("nif_SUITE:send_from_thread", &mti.p->tid,
+ threaded_sender, mti.p, NULL) != 0) {
+ return enif_make_badarg(env);
+ }
+ if (enif_is_identical(argv[2],atom_join)) {
+ int err = enif_thread_join(mti.p->tid, NULL);
+ assert(err == 0);
+ return enif_make_tuple3(env, atom_ok, enif_make_int(env, mti.p->send_res), copy);
+ }
+ else {
+ enif_keep_resource(mti.vp);
+ return enif_make_tuple2(env, atom_ok, copy);
+ }
+}
+
+static ERL_NIF_TERM join_send_thread(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+ union { void* vp; struct make_term_info* p; }mti;
+ int err;
+ if (!enif_get_resource(env, argv[0], msgenv_resource_type, &mti.vp)) {
+ return enif_make_badarg(env);
+ }
+ enif_mutex_lock(mti.p->mtx);
+ mti.p->send_it = 1;
+ enif_cond_signal(mti.p->cond);
+ enif_mutex_unlock(mti.p->mtx);
+ err = enif_thread_join(mti.p->tid, NULL);
+ assert(err == 0);
+ enif_release_resource(mti.vp);
+ return enif_make_tuple2(env, atom_ok, enif_make_int(env, mti.p->send_res));
+}
+
static ErlNifFunc nif_funcs[] =
{
@@ -656,8 +1277,21 @@ static ErlNifFunc nif_funcs[] =
{"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}
-
+ {"make_new_resource", 2, make_new_resource},
+ {"check_is", 10, check_is},
+ {"length_test", 5, length_test},
+ {"make_atoms", 0, make_atoms},
+ {"make_strings", 0, make_strings},
+ {"make_new_resource", 2, make_new_resource},
+ {"make_new_resource_binary", 1, make_new_resource_binary},
+ {"send_list_seq", 2, send_list_seq},
+ {"send_new_blob", 2, send_new_blob},
+ {"alloc_msgenv", 0, alloc_msgenv},
+ {"clear_msgenv", 1, clear_msgenv},
+ {"grow_blob", 2, grow_blob},
+ {"send_blob", 2, send_blob},
+ {"send_blob_thread", 3, send_blob_thread},
+ {"join_send_thread", 1, join_send_thread}
};
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 75df9d56d5..e32d10057c 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.c
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.c
@@ -42,6 +42,11 @@ static ERL_NIF_TERM am_resource_type;
static ERL_NIF_TERM am_resource_dtor_A;
static ERL_NIF_TERM am_resource_dtor_B;
+static NifModPrivData* priv_data(ErlNifEnv* env)
+{
+ return (NifModPrivData*) enif_priv_data(env);
+}
+
static void init(ErlNifEnv* env)
{
am_true = enif_make_atom(env, "true");
@@ -54,7 +59,7 @@ static void init(ErlNifEnv* env)
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) + arg_sz);
+ CallInfo* call = (CallInfo*)enif_alloc(sizeof(CallInfo)+strlen(func_name) + arg_sz);
strcpy(call->func_name, func_name);
call->lib_ver = NIF_LIB_VER;
call->static_cntA = ++static_cntA;
@@ -78,7 +83,7 @@ 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 ADD_CALL(FUNC_NAME) add_call(env, priv_data(env),FUNC_NAME)
#define STRINGIFY_(X) #X
#define STRINGIFY(X) STRINGIFY_(X)
@@ -87,56 +92,56 @@ 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));
+ add_call_with_arg(env, priv_data(env), dtor_name, (const char*)a,
+ enif_sizeof_resource(a));
}
static void resource_dtor_B(ErlNifEnv* env, void* a)
{
- const char dtor_name[] = "resource_dtor_B_v" STRINGIFY(NIF_LIB_VER);
+ 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));
+ add_call_with_arg(env, priv_data(env), dtor_name, (const char*)a,
+ enif_sizeof_resource(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);
+ NifModPrivData* data = 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;
+ union { 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_is_identical(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)) {
+ if (enif_is_identical(arr[4], am_null)) {
dtor = NULL;
}
- else if (enif_is_identical(env, arr[4], am_resource_dtor_A)) {
+ else if (enif_is_identical(arr[4], am_resource_dtor_A)) {
dtor = resource_dtor_A;
}
else {
- CHECK(enif_is_identical(env, arr[4], am_resource_dtor_B));
+ CHECK(enif_is_identical(arr[4], am_resource_dtor_B));
dtor = resource_dtor_B;
}
- got_ptr = enif_open_resource_type(env, rt_name, dtor,
+ got_ptr = enif_open_resource_type(env, NULL, 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(enif_is_identical(arr[1], am_null));
CHECK(got_ptr == NULL);
}
CHECK(got_res.e == exp_res.e);
@@ -144,7 +149,7 @@ static void open_resource_type(ErlNifEnv* env, ERL_NIF_TERM op_tpl)
static void do_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info)
{
- NifModPrivData* data = enif_priv_data(env);
+ NifModPrivData* data = priv_data(env);
ERL_NIF_TERM head, tail;
unsigned ix;
for (ix=0; ix<RT_MAX; ix++) {
@@ -158,17 +163,18 @@ static void do_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info)
CHECK(enif_is_empty_list(env, head));
}
-static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+static int load(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
NifModPrivData* data;
init(env);
- data = enif_alloc(env, sizeof(NifModPrivData));
+ data = (NifModPrivData*) enif_alloc(sizeof(NifModPrivData));
CHECK(data != NULL);
- *priv_data = data;
+ *priv = data;
data->mtx = enif_mutex_create("nif_mod_priv_data");
data->ref_cnt = 1;
data->call_history = NULL;
+
add_call(env, data, "load");
do_load_info(env, load_info);
@@ -176,39 +182,35 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
return 0;
}
-static int reload(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
+static int reload(ErlNifEnv* env, void** priv, ERL_NIF_TERM load_info)
{
+ NifModPrivData* data = (NifModPrivData*) *priv;
init(env);
- add_call(env, *priv_data, "reload");
+ add_call(env, 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)
+static int upgrade(ErlNifEnv* env, void** priv, void** old_priv_data, ERL_NIF_TERM load_info)
{
- NifModPrivData* data = *old_priv_data;
+ NifModPrivData* data = (NifModPrivData*) *old_priv_data;
init(env);
add_call(env, data, "upgrade");
data->ref_cnt++;
- *priv_data = *old_priv_data;
+ *priv = *old_priv_data;
do_load_info(env, load_info);
return 0;
}
-static void unload(ErlNifEnv* env, void* priv_data)
+static void unload(ErlNifEnv* env, void* priv)
{
- NifModPrivData* data = priv_data;
+ NifModPrivData* data = (NifModPrivData*) priv;
+ int is_last;
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);
+ NifModPrivData_release(data);
}
static ERL_NIF_TERM lib_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
@@ -220,12 +222,12 @@ static ERL_NIF_TERM lib_version(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
static ERL_NIF_TERM get_priv_data_ptr(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
ADD_CALL("get_priv_data_ptr");
- return enif_make_ulong(env, (unsigned long)enif_priv_data(env));
+ return enif_make_ulong(env, (unsigned long)priv_data(env));
}
static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- NifModPrivData* data = (NifModPrivData*) enif_priv_data(env);
+ NifModPrivData* data = priv_data(env);
ErlNifBinary ibin;
char* a;
ERL_NIF_TERM ret;
@@ -234,22 +236,22 @@ static ERL_NIF_TERM make_new_resource(ErlNifEnv* env, int argc, const ERL_NIF_TE
|| !enif_inspect_binary(env, argv[1], &ibin)) {
return enif_make_badarg(env);
}
- a = enif_alloc_resource(env, data->rt_arr[ix], ibin.size);
+ a = (char*) enif_alloc_resource(data->rt_arr[ix], ibin.size);
memcpy(a, ibin.data, ibin.size);
ret = enif_make_resource(env, a);
- enif_release_resource(env, a);
+ enif_release_resource(a);
return ret;
}
static ERL_NIF_TERM get_resource(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
- NifModPrivData* data = (NifModPrivData*) enif_priv_data(env);
+ NifModPrivData* data = 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)) {
+ || !enif_alloc_binary(enif_sizeof_resource(a), &obin)) {
return enif_make_badarg(env);
}
memcpy(obin.data, a, obin.size);
diff --git a/erts/emulator/test/nif_SUITE_data/nif_mod.h b/erts/emulator/test/nif_SUITE_data/nif_mod.h
index 0eaf91d6e1..cd0ecf4b54 100644
--- a/erts/emulator/test/nif_SUITE_data/nif_mod.h
+++ b/erts/emulator/test/nif_SUITE_data/nif_mod.h
@@ -20,3 +20,15 @@ typedef struct
ErlNifResourceType* rt_arr[RT_MAX];
}NifModPrivData;
+#define NifModPrivData_release(NMPD) \
+ do { \
+ int is_last; \
+ enif_mutex_lock((NMPD)->mtx); \
+ is_last = (--(NMPD)->ref_cnt == 0); \
+ enif_mutex_unlock((NMPD)->mtx); \
+ if (is_last) { \
+ enif_mutex_destroy((NMPD)->mtx); \
+ enif_free((NMPD)); \
+ } \
+ }while (0)
+
diff --git a/erts/emulator/test/port_SUITE.erl b/erts/emulator/test/port_SUITE.erl
index eb69bf917b..66aff307a3 100644
--- a/erts/emulator/test/port_SUITE.erl
+++ b/erts/emulator/test/port_SUITE.erl
@@ -88,7 +88,7 @@
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, close_deaf_port/1,
unregister_name/1]).
-export([]).
@@ -113,7 +113,7 @@ 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, close_deaf_port,
unregister_name
].
@@ -2293,3 +2293,12 @@ load_driver(Dir, Driver) ->
io:format("~s\n", [erl_ddll:format_error(Error)]),
Res
end.
+
+
+close_deaf_port(doc) -> ["Send data to port program that does not read it, then close port."];
+close_deaf_port(suite) -> [];
+close_deaf_port(Config) when is_list(Config) ->
+ Port = open_port({spawn,"sleep 999999"},[]),
+ erlang:port_command(Port,"Hello, can you hear me!?!?"),
+ port_close(Port),
+ ok.
diff --git a/erts/emulator/test/receive_SUITE.erl b/erts/emulator/test/receive_SUITE.erl
new file mode 100644
index 0000000000..40ebf2bd21
--- /dev/null
+++ b/erts/emulator/test/receive_SUITE.erl
@@ -0,0 +1,113 @@
+%%
+%% %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(receive_SUITE).
+
+%% Tests receive after.
+
+-include("test_server.hrl").
+
+-export([all/1,
+ call_with_huge_message_queue/1,receive_in_between/1]).
+
+-export([init_per_testcase/2,fin_per_testcase/2]).
+
+all(suite) ->
+ [call_with_huge_message_queue,receive_in_between].
+
+init_per_testcase(Func, Config) when is_atom(Func), is_list(Config) ->
+ Dog=?t:timetrap(?t:minutes(3)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Func, Config) ->
+ Dog=?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog).
+
+call_with_huge_message_queue(Config) when is_list(Config) ->
+ ?line Pid = spawn_link(fun echo_loop/0),
+
+ ?line {Time,ok} = tc(fun() -> calls(10, Pid) end),
+
+ ?line [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ erlang:garbage_collect(),
+ ?line {NewTime,ok} = tc(fun() -> calls(10, Pid) end),
+ io:format("Time for empty message queue: ~p", [Time]),
+ io:format("Time for huge message queue: ~p", [NewTime]),
+
+ case (NewTime+1) / (Time+1) of
+ Q when Q < 10 ->
+ ok;
+ Q ->
+ io:format("Q = ~p", [Q]),
+ ?line ?t:fail()
+ end,
+ ok.
+
+calls(0, _) -> ok;
+calls(N, Pid) ->
+ {ok,{ultimate_answer,42}} = call(Pid, {ultimate_answer,42}),
+ calls(N-1, Pid).
+
+call(Pid, Msg) ->
+ Mref = erlang:monitor(process, Pid),
+ Pid ! {Mref,{self(),Msg}},
+ receive
+ {Mref, Reply} ->
+ erlang:demonitor(Mref, [flush]),
+ {ok, Reply};
+ {'DOWN', Mref, _, _, Reason} ->
+ exit(Reason)
+ end.
+
+receive_in_between(Config) when is_list(Config) ->
+ ?line Pid = spawn_link(fun echo_loop/0),
+ ?line [{ok,{a,b}} = call2(Pid, {a,b}) || _ <- lists:seq(1, 100000)],
+ ok.
+
+call2(Pid, Msg) ->
+ self() ! dummy,
+ Mref = erlang:monitor(process, Pid),
+ Pid ! {Mref,{self(),Msg}},
+ receive_one(),
+ receive
+ {Mref,Reply} ->
+ erlang:demonitor(Mref, [flush]),
+ {ok,Reply};
+ {'DOWN',Mref,_,_,Reason} ->
+ exit(Reason)
+ end.
+
+receive_one() ->
+ receive
+ dummy -> ok
+ end.
+
+%%%
+%%% Common helpers.
+%%%
+
+echo_loop() ->
+ receive
+ {Ref,{Pid,Msg}} ->
+ Pid ! {Ref,Msg},
+ echo_loop()
+ end.
+
+tc(Fun) ->
+ timer:tc(erlang, apply, [Fun,[]]).
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index c9101b77c2..ab727b7cb1 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -902,7 +902,8 @@ scheduler_suspend_test(Config, Schedulers) ->
?line [SState] = mcall(Node, [fun () ->
erlang:system_info(schedulers_state)
end]),
- ?line {Sched, _, _} = SState,
+ ?line ?t:format("SState=~p~n", [SState]),
+ ?line {Sched, SchedOnln, _SchedAvail} = SState,
?line true = is_integer(Sched),
?line [ok] = mcall(Node, [fun () -> sst0_loop(300) end]),
?line [ok] = mcall(Node, [fun () -> sst1_loop(300) end]),
@@ -914,6 +915,14 @@ scheduler_suspend_test(Config, Schedulers) ->
fun () -> sst2_loop(200) end,
fun () -> sst3_loop(Sched, 200) end]),
?line [SState] = mcall(Node, [fun () ->
+ case Sched == SchedOnln of
+ false ->
+ Sched = erlang:system_flag(
+ schedulers_online,
+ SchedOnln);
+ true ->
+ ok
+ end,
erlang:system_info(schedulers_state)
end]),
?line stop_node(Node),
diff --git a/erts/epmd/src/epmd_int.h b/erts/epmd/src/epmd_int.h
index 84578c72f8..5ead553f36 100644
--- a/erts/epmd/src/epmd_int.h
+++ b/erts/epmd/src/epmd_int.h
@@ -141,6 +141,10 @@
# define EADDRINUSE WSAEADDRINUSE
#endif
+#if defined(__WIN32__) && !defined(ECONNABORTED)
+# define ECONNABORTED WSAECONNABORTED
+#endif
+
#ifndef SOMAXCONN
# define SOMAXCONN 128
#endif
diff --git a/erts/epmd/src/epmd_srv.c b/erts/epmd/src/epmd_srv.c
index 021f8207eb..34f657fb16 100644
--- a/erts/epmd/src/epmd_srv.c
+++ b/erts/epmd/src/epmd_srv.c
@@ -210,8 +210,16 @@ void run(EpmdVars *g)
timeout.tv_sec = (g->packet_timeout < IDLE_TIMEOUT) ? 1 : IDLE_TIMEOUT;
timeout.tv_usec = 0;
- if ((ret = select(g->max_conn,&read_mask,(fd_set *)0,(fd_set *)0,&timeout)) < 0)
+ if ((ret = select(g->max_conn,&read_mask,(fd_set *)0,(fd_set *)0,&timeout)) < 0) {
dbg_perror(g,"error in select ");
+ switch (errno) {
+ case EAGAIN:
+ case EINTR:
+ break;
+ default:
+ epmd_cleanup_exit(g,1);
+ }
+ }
else {
time_t now;
if (ret == 0) {
@@ -384,7 +392,14 @@ static int do_accept(EpmdVars *g,int listensock)
if (msgsock < 0) {
dbg_perror(g,"error in accept");
- return EPMD_FALSE;
+ switch (errno) {
+ case EAGAIN:
+ case ECONNABORTED:
+ case EINTR:
+ return EPMD_FALSE;
+ default:
+ epmd_cleanup_exit(g,1);
+ }
}
return conn_open(g,msgsock);
diff --git a/erts/include/internal/ethread.h b/erts/include/internal/ethread.h
index 934a79c6f9..4e7a38cd5c 100644
--- a/erts/include/internal/ethread.h
+++ b/erts/include/internal/ethread.h
@@ -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%
*/
@@ -375,6 +375,12 @@ ETHR_INLINE_FUNC_NAME_(ethr_mutex_unlock)(ethr_mutex *mtx)
#define ETHR_HAVE_OPTIMIZED_ATOMIC_OPS 1
#define ETHR_HAVE_OPTIMIZED_LOCKS 1
+#define ETHR_MEMORY_BARRIER \
+do { \
+ volatile LONG x___ = 0; \
+ (void) _InterlockedCompareExchange(&x___, (LONG) 1, (LONG) 0); \
+} while (0)
+
typedef struct {
volatile LONG value;
} ethr_atomic_t;
@@ -688,25 +694,33 @@ ETHR_INLINE_FUNC_NAME_(ethr_write_lock)(ethr_rwlock_t *lock)
#endif
/* For CPU-optimised atomics, spinlocks, and rwlocks. */
-#if !defined(ETHR_DISABLE_NATIVE_IMPLS) && defined(__GNUC__)
-# if ETHR_SIZEOF_PTR == 4
-# if defined(__i386__)
-# include "i386/ethread.h"
-# elif (defined(__powerpc__) || defined(__ppc__)) && !defined(__powerpc64__)
-# include "ppc32/ethread.h"
-# elif defined(__sparc__)
-# include "sparc32/ethread.h"
-# elif defined(__tile__)
-# include "tile/ethread.h"
+#if !defined(ETHR_DISABLE_NATIVE_IMPLS)
+# if defined(__GNUC__)
+# if defined(ETHR_PREFER_GCC_NATIVE_IMPLS)
+# include "gcc/ethread.h"
# endif
-# elif ETHR_SIZEOF_PTR == 8
-# if defined(__x86_64__)
-# include "x86_64/ethread.h"
-# elif defined(__sparc__) && defined(__arch64__)
-# include "sparc64/ethread.h"
+# ifndef ETHR_HAVE_NATIVE_ATOMICS
+# if ETHR_SIZEOF_PTR == 4
+# if defined(__i386__)
+# include "i386/ethread.h"
+# elif (defined(__powerpc__)||defined(__ppc__))&&!defined(__powerpc64__)
+# include "ppc32/ethread.h"
+# elif defined(__sparc__)
+# include "sparc32/ethread.h"
+# elif defined(__tile__)
+# include "tile/ethread.h"
+# endif
+# elif ETHR_SIZEOF_PTR == 8
+# if defined(__x86_64__)
+# include "x86_64/ethread.h"
+# elif defined(__sparc__) && defined(__arch64__)
+# include "sparc64/ethread.h"
+# endif
+# endif
+# include "gcc/ethread.h"
# endif
# endif
-#endif /* !defined(ETHR_DISABLE_NATIVE_IMPLS) && defined(__GNUC__) */
+#endif /* !defined(ETHR_DISABLE_NATIVE_IMPLS) */
#ifdef ETHR_HAVE_OPTIMIZED_ATOMIC_OPS
# undef ETHR_HAVE_NATIVE_ATOMICS
@@ -1124,8 +1138,14 @@ ETHR_INLINE_FUNC_NAME_(ethr_write_lock)(ethr_rwlock_t *lock)
*/
#ifndef ETHR_HAVE_OPTIMIZED_ATOMIC_OPS
-#define ETHR_ATOMIC_ADDR_BITS 4
-#define ETHR_ATOMIC_ADDR_SHIFT 3
+/*
+ * ETHR_MEMORY_BARRIER orders between locked and atomic accesses only,
+ * i.e. when this atomic fallback is used a noop is sufficient.
+ */
+#define ETHR_MEMORY_BARRIER
+
+#define ETHR_ATOMIC_ADDR_BITS 10
+#define ETHR_ATOMIC_ADDR_SHIFT 6
typedef struct {
union {
diff --git a/erts/include/internal/ethread_header_config.h.in b/erts/include/internal/ethread_header_config.h.in
index e5b4946a53..c9fd87c2f6 100644
--- a/erts/include/internal/ethread_header_config.h.in
+++ b/erts/include/internal/ethread_header_config.h.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%
*/
@@ -50,6 +50,19 @@
/* Define if you have a pthread_rwlock implementation that can be used */
#undef ETHR_HAVE_PTHREAD_RWLOCK_INIT
+/* Define if you have the pthread_rwlockattr_setkind_np() function. */
+#undef ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP
+
+/* Define if you have the PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP rwlock
+ attribute. */
+#undef ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
+
+/* Define if you have gcc atomic operations */
+#undef ETHR_HAVE_GCC_ATOMIC_OPS
+
+/* Define if you prefer gcc native ethread implementations */
+#undef ETHR_PREFER_GCC_NATIVE_IMPLS
+
/* Define if you want to turn on extra sanity checking in the ethread library */
#undef ETHR_XCHK
diff --git a/erts/include/internal/gcc/ethr_atomic.h b/erts/include/internal/gcc/ethr_atomic.h
new file mode 100644
index 0000000000..775030c8d5
--- /dev/null
+++ b/erts/include/internal/gcc/ethr_atomic.h
@@ -0,0 +1,164 @@
+/*
+ * %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: Native atomics ethread support using gcc's builtins
+ * Author: Rickard Green
+ */
+
+#ifndef ETHR_GCC_ATOMIC_H__
+#define ETHR_GCC_ATOMIC_H__
+
+#if !defined(ETHR_HAVE_NATIVE_ATOMICS) && defined(ETHR_HAVE_GCC_ATOMIC_OPS)
+#define ETHR_HAVE_NATIVE_ATOMICS 1
+
+#define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 0
+/* Enable immediate read/write on platforms where we know it is safe */
+#if defined(__i386__) || defined(__x86_64__) || defined(__sparc__) \
+ || defined(__powerpc__) || defined(__ppc__)
+# undef ETHR_IMMED_ATOMIC_SET_GET_SAFE__
+# define ETHR_IMMED_ATOMIC_SET_GET_SAFE__ 1
+#endif
+
+typedef struct {
+ volatile long counter;
+} ethr_native_atomic_t;
+
+
+/*
+ * According to the documentation this is what we want:
+ * #define ETHR_MEMORY_BARRIER __sync_synchronize()
+ * However, __sync_synchronize() is known to erroneously be
+ * a noop on at least some platforms with some gcc versions.
+ * This has suposedly been fixed in some gcc version, but we
+ * don't know from which version. Therefore, we use the
+ * workaround implemented below on all gcc versions.
+ */
+#define ETHR_MEMORY_BARRIER \
+do { \
+ volatile long x___ = 0; \
+ (void) __sync_val_compare_and_swap(&x___, (long) 0, (long) 1); \
+} while (0)
+
+#if defined(ETHR_TRY_INLINE_FUNCS) || defined(ETHR_AUX_IMPL__)
+
+static ETHR_INLINE void
+ethr_native_atomic_set(ethr_native_atomic_t *var, long value)
+{
+#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
+ var->counter = value;
+#else
+ /*
+ * Unfortunately no __sync_store() or similar exist in the gcc atomic
+ * op interface. We therefore have to simulate it this way...
+ */
+ long act = 0, exp;
+ do {
+ exp = act;
+ act = __sync_val_compare_and_swap(&var->counter, exp, value);
+ } while (act != exp);
+#endif
+}
+
+#define ethr_native_atomic_init ethr_native_atomic_set
+
+static ETHR_INLINE long
+ethr_native_atomic_read(ethr_native_atomic_t *var)
+{
+#if ETHR_IMMED_ATOMIC_SET_GET_SAFE__
+ return var->counter;
+#else
+ /*
+ * Unfortunately no __sync_fetch() or similar exist in the gcc atomic
+ * op interface. We therefore have to simulate it this way...
+ */
+ return __sync_add_and_fetch(&var->counter, (long) 0);
+#endif
+}
+
+static ETHR_INLINE void
+ethr_native_atomic_add(ethr_native_atomic_t *var, long incr)
+{
+ (void) __sync_add_and_fetch(&var->counter, incr);
+}
+
+static ETHR_INLINE long
+ethr_native_atomic_add_return(ethr_native_atomic_t *var, long incr)
+{
+ return __sync_add_and_fetch(&var->counter, incr);
+}
+
+static ETHR_INLINE void
+ethr_native_atomic_inc(ethr_native_atomic_t *var)
+{
+ (void) __sync_add_and_fetch(&var->counter, (long) 1);
+}
+
+static ETHR_INLINE void
+ethr_native_atomic_dec(ethr_native_atomic_t *var)
+{
+ (void) __sync_sub_and_fetch(&var->counter, (long) 1);
+}
+
+static ETHR_INLINE long
+ethr_native_atomic_inc_return(ethr_native_atomic_t *var)
+{
+ return __sync_add_and_fetch(&var->counter, (long) 1);
+}
+
+static ETHR_INLINE long
+ethr_native_atomic_dec_return(ethr_native_atomic_t *var)
+{
+ return __sync_sub_and_fetch(&var->counter, (long) 1);
+}
+
+static ETHR_INLINE long
+ethr_native_atomic_and_retold(ethr_native_atomic_t *var, long mask)
+{
+ return __sync_fetch_and_and(&var->counter, mask);
+}
+
+static ETHR_INLINE long
+ethr_native_atomic_or_retold(ethr_native_atomic_t *var, long mask)
+{
+ return (long) __sync_fetch_and_or(&var->counter, mask);
+}
+
+static ETHR_INLINE long
+ethr_native_atomic_cmpxchg(ethr_native_atomic_t *var, long new, long old)
+{
+ return __sync_val_compare_and_swap(&var->counter, old, new);
+}
+
+static ETHR_INLINE long
+ethr_native_atomic_xchg(ethr_native_atomic_t *var, long new)
+{
+ long exp, act = 0;
+ do {
+ exp = act;
+ act = __sync_val_compare_and_swap(&var->counter, exp, new);
+ } while (act != exp);
+ return act;
+}
+
+#endif
+
+#endif
+
+#endif
diff --git a/erts/include/internal/gcc/ethread.h b/erts/include/internal/gcc/ethread.h
new file mode 100644
index 0000000000..bb378e31e0
--- /dev/null
+++ b/erts/include/internal/gcc/ethread.h
@@ -0,0 +1,30 @@
+/*
+ * %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: Native atomic ethread support when using gcc
+ * Author: Rickard Green
+ */
+
+#ifndef ETHREAD_GCC_H__
+#define ETHREAD_GCC_H__
+
+#include "ethr_atomic.h"
+
+#endif
diff --git a/erts/include/internal/i386/atomic.h b/erts/include/internal/i386/atomic.h
index 3291ad38e5..90b4c5f773 100644
--- a/erts/include/internal/i386/atomic.h
+++ b/erts/include/internal/i386/atomic.h
@@ -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,6 +32,16 @@ typedef struct {
volatile long counter;
} ethr_native_atomic_t;
+#ifdef __x86_64__
+#define ETHR_MEMORY_BARRIER __asm__ __volatile__("mfence" : : : "memory")
+#else
+#define ETHR_MEMORY_BARRIER \
+do { \
+ volatile long x___ = 0; \
+ __asm__ __volatile__("lock; incl %0" : "=m"(x___) : "m"(x___) : "memory"); \
+} while (0)
+#endif
+
#ifdef ETHR_TRY_INLINE_FUNCS
#ifdef __x86_64__
diff --git a/erts/include/internal/ppc32/atomic.h b/erts/include/internal/ppc32/atomic.h
index fa701c6a92..105d874995 100644
--- a/erts/include/internal/ppc32/atomic.h
+++ b/erts/include/internal/ppc32/atomic.h
@@ -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,6 +32,7 @@ typedef struct {
volatile int counter;
} ethr_native_atomic_t;
+#define ETHR_MEMORY_BARRIER __asm__ __volatile__("sync" : : : "memory")
#ifdef ETHR_TRY_INLINE_FUNCS
diff --git a/erts/include/internal/sparc32/atomic.h b/erts/include/internal/sparc32/atomic.h
index d6fdc6b2a4..8fde449a52 100644
--- a/erts/include/internal/sparc32/atomic.h
+++ b/erts/include/internal/sparc32/atomic.h
@@ -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%
*/
@@ -28,6 +28,10 @@ typedef struct {
volatile long counter;
} ethr_native_atomic_t;
+#define ETHR_MEMORY_BARRIER \
+ __asm__ __volatile__("membar #LoadLoad|#LoadStore|#StoreLoad|#StoreStore\n" \
+ : : : "memory")
+
#ifdef ETHR_TRY_INLINE_FUNCS
#if defined(__arch64__)
diff --git a/erts/include/internal/tile/atomic.h b/erts/include/internal/tile/atomic.h
index 59a9250e7c..5e4c7ac9fe 100644
--- a/erts/include/internal/tile/atomic.h
+++ b/erts/include/internal/tile/atomic.h
@@ -32,6 +32,8 @@ typedef struct {
volatile long counter;
} ethr_native_atomic_t;
+#define ETHR_MEMORY_BARRIER __insn_mf()
+
#ifdef ETHR_TRY_INLINE_FUNCS
static ETHR_INLINE void
diff --git a/erts/lib_src/Makefile.in b/erts/lib_src/Makefile.in
index 49f5b1f048..e7caac8072 100644
--- a/erts/lib_src/Makefile.in
+++ b/erts/lib_src/Makefile.in
@@ -447,7 +447,7 @@ INTERNAL_RELEASE_INCLUDES= \
$(ERTS_INCL_INT)/erl_misc_utils.h \
$(ERTS_INCL_INT)/erl_errno.h
-INTERNAL_X_RELEASE_INCLUDE_DIRS= i386 x86_64 ppc32 sparc32 sparc64 tile
+INTERNAL_X_RELEASE_INCLUDE_DIRS= i386 x86_64 ppc32 sparc32 sparc64 tile gcc
INTERNAL_RELEASE_LIBS= \
../lib/internal/README \
diff --git a/erts/lib_src/common/ethread.c b/erts/lib_src/common/ethread.c
index eb4d0cad20..9c88233934 100644
--- a/erts/lib_src/common/ethread.c
+++ b/erts/lib_src/common/ethread.c
@@ -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%
*/
@@ -269,6 +269,11 @@ static ethr_mutex no_ethrs_mtx;
#warning "Cannot enforce fork-safety"
#endif
+#ifdef ETHR_HAVE_PTHREAD_RWLOCK_INIT
+static pthread_rwlockattr_t write_pref_attr_data;
+static pthread_rwlockattr_t *write_pref_attr;
+#endif
+
/*
* ----------------------------------------------------------------------------
* Static functions
@@ -525,6 +530,24 @@ ethr_init(ethr_init_data *id)
}
#endif
+#ifdef ETHR_HAVE_PTHREAD_RWLOCK_INIT
+#if defined(ETHR_HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) \
+ && defined(ETHR_HAVE_PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP)
+ res = pthread_rwlockattr_init(&write_pref_attr_data);
+ if (res != 0)
+ goto error;
+ res = pthread_rwlockattr_setkind_np(
+ &write_pref_attr_data,
+ PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
+ if (res != 0)
+ goto error;
+ write_pref_attr = &write_pref_attr_data;
+#else
+ write_pref_attr = NULL;
+#endif
+#endif
+
+
return 0;
error:
@@ -1060,7 +1083,7 @@ ethr_rwmutex_init(ethr_rwmutex *rwmtx)
}
rwmtx->initialized = ETHR_RWMUTEX_INITIALIZED;
#endif
- return pthread_rwlock_init(&rwmtx->pt_rwlock, NULL);
+ return pthread_rwlock_init(&rwmtx->pt_rwlock, write_pref_attr);
}
int
@@ -3193,7 +3216,7 @@ ethr_rwmutex_tryrlock(ethr_rwmutex *rwmtx)
res = ethr_mutex_trylock__(&rwmtx->mtx);
if (res != 0)
return res;
- if (!rwmtx->waiting_writers) {
+ if (rwmtx->waiting_writers) {
res = ethr_mutex_unlock__(&rwmtx->mtx);
if (res == 0)
return EBUSY;
diff --git a/erts/preloaded/ebin/erl_prim_loader.beam b/erts/preloaded/ebin/erl_prim_loader.beam
index afd8a90b3f..0d2be9e1ea 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 4ec84948d8..a33a570891 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 c3e746f3ee..2cb7d3bd25 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 4b2d8bb2de..4c1e8aa63f 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 2916baaa77..d39d2d1135 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 46912e2bea..52d1d9215f 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 ccf8aff6f6..d31de6cfd3 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 ccd597ba68..ac4537662b 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 a13292d5ab..024b20eadb 100644
--- a/erts/preloaded/src/erl_prim_loader.erl
+++ b/erts/preloaded/src/erl_prim_loader.erl
@@ -405,7 +405,7 @@ handle_timeout(State = #state{loader = inet}, Parent) ->
efile_multi_get_file_from_port(State, ModFiles, Paths, Fun) ->
Ref = make_ref(),
%% More than 200 processes is no gain.
- Max = min(200, erlang:system_info(thread_pool_size)),
+ Max = erlang:min(200, erlang:system_info(thread_pool_size)),
efile_multi_get_file_from_port2(ModFiles, 0, Max, State, Paths, Fun, Ref, ok).
efile_multi_get_file_from_port2([MF | MFs], Out, Max, State, Paths, Fun, Ref, Ret) when Out < Max ->
@@ -1189,9 +1189,6 @@ keyins(X, I, [Y | T]) when X < element(I,Y) -> [X,Y|T];
keyins(X, I, [Y | T]) -> [Y | keyins(X, I, T)];
keyins(X, _I, []) -> [X].
-min(X, Y) when X < Y -> X;
-min(_X, Y) -> Y.
-
to_strs([P|Paths]) when is_atom(P) ->
[atom_to_list(P)|to_strs(Paths)];
to_strs([P|Paths]) when is_list(P) ->
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 1edb5e72db..935c2de253 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -44,7 +44,14 @@
-deprecated([hash/2]).
-deprecated([concat_binary/1]).
--compile(nowarn_bif_clash).
+% Get rid of autoimports of spawn to avoid clashes with ourselves.
+-compile({no_auto_import,[spawn/1]}).
+-compile({no_auto_import,[spawn/4]}).
+-compile({no_auto_import,[spawn_link/1]}).
+-compile({no_auto_import,[spawn_link/4]}).
+-compile({no_auto_import,[spawn_opt/2]}).
+-compile({no_auto_import,[spawn_opt/4]}).
+-compile({no_auto_import,[spawn_opt/5]}).
%%--------------------------------------------------------------------------
@@ -55,10 +62,10 @@
%%--------------------------------------------------------------------------
apply(Fun, Args) ->
- apply(Fun, Args).
+ erlang:apply(Fun, Args).
apply(Mod, Name, Args) ->
- apply(Mod, Name, Args).
+ erlang:apply(Mod, Name, Args).
%% Spawns with a fun
diff --git a/erts/preloaded/src/prim_file.erl b/erts/preloaded/src/prim_file.erl
index 43e6f6cd88..2d177bf80e 100644
--- a/erts/preloaded/src/prim_file.erl
+++ b/erts/preloaded/src/prim_file.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(prim_file).
@@ -25,7 +25,7 @@
%%% Interface towards a single file's contents. Uses ?FD_DRV.
%% Generic file contents operations
--export([open/2, close/1, sync/1, position/2, truncate/1,
+-export([open/2, close/1, datasync/1, sync/1, advise/4, position/2, truncate/1,
write/2, pwrite/2, pwrite/3, read/2, read_line/1, pread/2, pread/3, copy/3]).
%% Specialized file operations
@@ -96,6 +96,8 @@
-define(FILE_IPREAD, 27).
-define(FILE_ALTNAME, 28).
-define(FILE_READ_LINE, 29).
+-define(FILE_FDATASYNC, 30).
+-define(FILE_ADVISE, 31).
%% Driver responses
-define(FILE_RESP_OK, 0).
@@ -130,6 +132,13 @@
%% IPREAD variants
-define(IPREAD_S32BU_P32BU, 0).
+%% POSIX file advises
+-define(POSIX_FADV_NORMAL, 0).
+-define(POSIX_FADV_RANDOM, 1).
+-define(POSIX_FADV_SEQUENTIAL, 2).
+-define(POSIX_FADV_WILLNEED, 3).
+-define(POSIX_FADV_DONTNEED, 4).
+-define(POSIX_FADV_NOREUSE, 5).
%%%-----------------------------------------------------------------
@@ -220,7 +229,35 @@ close(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
close(Port) when is_port(Port) ->
drv_close(Port).
+-define(ADVISE(Offs, Len, Adv),
+ <<?FILE_ADVISE, Offs:64/signed, Len:64/signed,
+ Adv:32/signed>>).
+%% Returns {error, Reason} | ok.
+advise(#file_descriptor{module = ?MODULE, data = {Port, _}},
+ Offset, Length, Advise) ->
+ case Advise of
+ normal ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NORMAL),
+ drv_command(Port, Cmd);
+ random ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_RANDOM),
+ drv_command(Port, Cmd);
+ sequential ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_SEQUENTIAL),
+ drv_command(Port, Cmd);
+ will_need ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_WILLNEED),
+ drv_command(Port, Cmd);
+ dont_need ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_DONTNEED),
+ drv_command(Port, Cmd);
+ no_reuse ->
+ Cmd = ?ADVISE(Offset, Length, ?POSIX_FADV_NOREUSE),
+ drv_command(Port, Cmd);
+ _ ->
+ {error, einval}
+ end.
%% Returns {error, Reason} | ok.
write(#file_descriptor{module = ?MODULE, data = {Port, _}}, Bytes) ->
@@ -292,6 +329,9 @@ pwrite(#file_descriptor{module = ?MODULE}, _, _) ->
{error, badarg}.
+%% Returns {error, Reason} | ok.
+datasync(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
+ drv_command(Port, [?FILE_FDATASYNC]).
%% Returns {error, Reason} | ok.
sync(#file_descriptor{module = ?MODULE, data = {Port, _}}) ->
diff --git a/lib/appmon/src/appmon.erl b/lib/appmon/src/appmon.erl
index 6f5d2824d2..2b982cddf0 100644
--- a/lib/appmon/src/appmon.erl
+++ b/lib/appmon/src/appmon.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(appmon).
-behaviour(gen_server).
@@ -838,7 +838,7 @@ draw_apps(GUI, [App | Apps], X, Lx0, N, GSObjs) ->
%% Some necessary data
{_Pid, AppName, _Descr} = App,
Text = atom_to_list(AppName),
- Width = max(8*length(Text)+10, ?wBTN),
+ Width = erlang:max(8*length(Text)+10, ?wBTN),
%% Connect the application to the node label with a line
%% Lx0 = leftmost X coordinate (above previous application button)
@@ -1009,9 +1009,6 @@ bcast(MNodes, Msg) ->
end,
MNodes).
-max(X, Y) when X>Y -> X;
-max(_, Y) -> Y.
-
%% parse_nodes(MNodes) -> NodeApps
%% MNodes -> [#mnode{}]
%% NodeApps -> [{Node, Status, Apps}]
diff --git a/lib/appmon/src/appmon_info.erl b/lib/appmon/src/appmon_info.erl
index 4e36d3a13f..332140f69d 100644
--- a/lib/appmon/src/appmon_info.erl
+++ b/lib/appmon/src/appmon_info.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%
%%
%%----------------------------------------------------------------------
@@ -807,24 +807,21 @@ load(Opts) ->
case get_opt(load_scale, Opts) of
linear ->
- min(trunc(load_range()*(Td/Tot+Q/6)),
+ erlang:min(trunc(load_range()*(Td/Tot+Q/6)),
load_range());
prog ->
- min(trunc(load_range()*prog(Td/Tot+Q/6)),
+ erlang:min(trunc(load_range()*prog(Td/Tot+Q/6)),
load_range())
end;
queue ->
case get_opt(load_scale, Opts) of
linear ->
- min(trunc(load_range()*Q/6), load_range());
+ erlang:min(trunc(load_range()*Q/6), load_range());
prog ->
- min(trunc(load_range()*prog(Q/6)), load_range())
+ erlang:min(trunc(load_range()*prog(Q/6)), load_range())
end
end.
-min(X,Y) when X<Y -> X;
-min(_,Y)->Y.
-
%%
%% T shall be within 0 and 0.9 for this to work correctly
diff --git a/lib/appmon/src/appmon_place.erl b/lib/appmon/src/appmon_place.erl
index 5a6ae6aa48..fe1e909d7c 100644
--- a/lib/appmon/src/appmon_place.erl
+++ b/lib/appmon/src/appmon_place.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%
%%------------------------------------------------------------
%%
@@ -155,10 +155,8 @@ move2(DG, V, LastX, DeltaX) ->
ChLX = foldl(fun(C, LX) -> move2(DG, C, LX, DeltaX) end,
tll(LastX),
appmon_dg:get(out, DG, V)),
- [max(NewX+appmon_dg:get(w, DG, V), hdd(LastX)) | ChLX].
+ [erlang:max(NewX+appmon_dg:get(w, DG, V), hdd(LastX)) | ChLX].
-max(A, B) when A>B -> A;
-max(_, B) -> B.
%%------------------------------------------------------------
%%
diff --git a/lib/asn1/c_src/Makefile b/lib/asn1/c_src/Makefile
index 906c513fad..9e9cb18524 100644
--- a/lib/asn1/c_src/Makefile
+++ b/lib/asn1/c_src/Makefile
@@ -124,7 +124,7 @@ 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_PROGRAM) $(SHARED_OBJ_FILES) $(RELSYSDIR)/priv/lib
$(INSTALL_DIR) $(RELSYSDIR)/c_src
$(INSTALL_DATA) $(C_FILES) $(RELSYSDIR)/c_src
diff --git a/lib/common_test/src/ct_ssh.erl b/lib/common_test/src/ct_ssh.erl
index f2b25b1fcd..aebb28bc42 100644
--- a/lib/common_test/src/ct_ssh.erl
+++ b/lib/common_test/src/ct_ssh.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%
%%
@@ -961,24 +961,25 @@ init(KeyOrName, {ConnType,Addr,Port}, AllOpts) ->
ssh ->
ssh:connect(Addr, Port, FinalOptions);
sftp ->
- ssh_sftp:connect(Addr, Port, FinalOptions)
+ ssh_sftp:start_channel(Addr, Port, FinalOptions)
end,
case Result of
- {ok,SSHRef} ->
+ Error = {error,_} ->
+ Error;
+ Ok ->
+ SSHRef = element(2, Ok),
log(heading(init,KeyOrName),
"Opened ~w connection:\nHost: ~p (~p)\nUser: ~p\nPassword: ~p\n",
[ConnType,Addr,Port,User,lists:duplicate(length(Password),$*)]),
{ok,SSHRef,#state{ssh_ref=SSHRef, conn_type=ConnType,
- target=KeyOrName}};
- Error ->
- Error
+ target=KeyOrName}}
end.
%% @hidden
handle_msg(sftp_connect, State) ->
#state{ssh_ref=SSHRef, target=Target} = State,
log(heading(sftp_connect,Target), "SSH Ref: ~p", [SSHRef]),
- {ssh_sftp:connect(SSHRef),State};
+ {ssh_sftp:start_channel(SSHRef),State};
handle_msg({session_open,TO}, State) ->
#state{ssh_ref=SSHRef, target=Target} = State,
@@ -1202,7 +1203,7 @@ terminate(SSHRef, State) ->
sftp ->
log(heading(disconnect_sftp,State#state.target),
"SFTP Ref: ~p",[SSHRef]),
- ssh_sftp:stop(SSHRef)
+ ssh_sftp:stop_channel(SSHRef)
end.
@@ -1213,7 +1214,6 @@ terminate(SSHRef, State) ->
%%%
do_recv_response(SSH, Chn, Data, End, Timeout) ->
receive
-
{ssh_cm, SSH, {open,Chn,RemoteChn,{session}}} ->
debug("RECVD open"),
{ok,{open,Chn,RemoteChn,{session}}};
diff --git a/lib/common_test/vsn.mk b/lib/common_test/vsn.mk
index ee07350c55..cdb8e1f71c 100644
--- a/lib/common_test/vsn.mk
+++ b/lib/common_test/vsn.mk
@@ -1,3 +1,3 @@
-COMMON_TEST_VSN = 1.4.7
+COMMON_TEST_VSN = 1.4.8
diff --git a/lib/compiler/doc/src/compile.xml b/lib/compiler/doc/src/compile.xml
index bbd3f1043d..e1f24b602d 100644
--- a/lib/compiler/doc/src/compile.xml
+++ b/lib/compiler/doc/src/compile.xml
@@ -310,6 +310,23 @@
(there will not even be a warning if there is a mismatch).</p>
</item>
+ <tag><c>{no_auto_import,[F/A, ...]}</c></tag>
+ <item>
+ <p>Makes the function <c>F/A</c> no longer beeing
+ auto-imported from the module <c>erlang</c>, which resolves
+ BIF name clashes. This option has to be used to resolve name
+ clashes with BIFs auto-imported before R14A, if one wants to
+ call the local function with the same name as an
+ auto-imported BIF without module prefix.</p>
+ <note>
+ <p>From R14A and forward, the compiler resolves calls
+ without module prefix to local or imported functions before
+ trying auto-imported BIFs. If the BIF is to be
+ called, use the <c>erlang</c> module prefix in the call, not
+ <c>{ no_auto_import,[F/A, ...]}</c></p>
+ </note>
+ </item>
+
</taglist>
<p>If warnings are turned on (the <c>report_warnings</c> option
@@ -338,31 +355,35 @@
<tag><c>nowarn_bif_clash</c></tag>
<item>
- <p>By default, there will be a compilation error if a
- module contains an exported function with the same name
- as an auto-imported BIF (such as <c>size/1</c>) AND
- there is a call to it without a qualifying module name.
- The reason is that the BIF will be called, not
- the function in the same module. The recommended way to
- eliminate that warning is to use a call with a module
- name - either <c>erlang</c> to call the BIF or
- <c>?MODULE</c> to call the function in the same module.
- The warning can also be turned off using this option,
- but that is not recommended.</p>
+ <p>This option is removed, it will generate a fatal error if used.</p>
+
+ <warning>
+ <p>Beginning with R14A, the compiler no longer calls the
+ auto-imported BIF if the name clashes with a local or
+ explicitly imported function and a call without explicit
+ module name is issued. Instead the local or imported
+ function is called. Still accepting <c>nowarn_bif_clash</c> would makes a
+ module calling functions clashing with autoimported BIFs
+ compile with both the old and new compilers, but with
+ completely different semantics, why the option was removed.</p>
- <p><em>The use of this option is strongly discouraged,
- as code that uses it will probably break in a future
- major release (R14 or R15).</em></p>
+ <p>The use of this option has always been strongly discouraged.
+ From OTP R14A and forward it's an error to use it.</p>
+ <p>To resolve BIF clashes, use explicit module names or the
+ <c>{no_auto_import,[F/A]}</c> compiler directive.</p>
+ </warning>
</item>
<tag><c>{nowarn_bif_clash, FAs}</c></tag>
<item>
- <p>Turns off warnings as <c>nowarn_bif_clash</c> but only
- for the mentioned local functions. <c>FAs</c> is a tuple
- <c>{Name,Arity}</c> or a list of such tuples.</p>
- <p><em>The use of this option is strongly discouraged,
- as code that uses it will probably break in a future
- major release (R14 or R15).</em></p>
+ <p>This option is removed, it will generate a fatal error if used.</p>
+
+ <warning>
+ <p>The use of this option has always been strongly discouraged.
+ From OTP R14A and forward it's an error to use it.</p>
+ <p>To resolve BIF clashes, use explicit module names or the
+ <c>{no_auto_import,[F/A]}</c> compiler directive.</p>
+ </warning>
</item>
<tag><c>warn_export_all</c></tag>
diff --git a/lib/compiler/src/Makefile b/lib/compiler/src/Makefile
index 70ddd54145..0f6d2f6193 100644
--- a/lib/compiler/src/Makefile
+++ b/lib/compiler/src/Makefile
@@ -58,6 +58,7 @@ MODULES = \
beam_listing \
beam_opcodes \
beam_peep \
+ beam_receive \
beam_trim \
beam_type \
beam_utils \
diff --git a/lib/compiler/src/beam_asm.erl b/lib/compiler/src/beam_asm.erl
index 497c4fa07b..89d64834cf 100644
--- a/lib/compiler/src/beam_asm.erl
+++ b/lib/compiler/src/beam_asm.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 : Assembler for threaded Beam.
@@ -23,7 +23,7 @@
-export([module/4]).
-export([encode/2]).
--import(lists, [map/2,member/2,keymember/3,duplicate/2,filter/2]).
+-import(lists, [map/2,member/2,keymember/3,duplicate/2]).
-include("beam_opcodes.hrl").
module(Code, Abst, SourceFile, Opts) ->
@@ -191,11 +191,7 @@ flatten_exports(Exps) ->
flatten_imports(Imps) ->
list_to_binary(map(fun({M,F,A}) -> <<M:32,F:32,A:32>> end, Imps)).
-build_attributes(Opts, SourceFile, Attr0, Essentials) ->
- Attr = filter(fun({type,_}) -> false;
- ({spec,_}) -> false;
- (_) -> true
- end, Attr0),
+build_attributes(Opts, SourceFile, Attr, Essentials) ->
Misc = case member(slim, Opts) of
false ->
{{Y,Mo,D},{H,Mi,S}} = erlang:universaltime(),
@@ -265,7 +261,8 @@ make_op({gc_bif,Bif,Fail,Live,Args,Dest}, Dict) ->
Arity = length(Args),
BifOp = case Arity of
1 -> gc_bif1;
- 2 -> gc_bif2
+ 2 -> gc_bif2;
+ 3 -> gc_bif3
end,
encode_op(BifOp, [Fail,Live,{extfunc,erlang,Bif,Arity}|Args++[Dest]],Dict);
make_op({bs_add=Op,Fail,[Src1,Src2,Unit],Dest}, Dict) ->
diff --git a/lib/compiler/src/beam_block.erl b/lib/compiler/src/beam_block.erl
index 32703b4dd1..9c6f835ab0 100644
--- a/lib/compiler/src/beam_block.erl
+++ b/lib/compiler/src/beam_block.erl
@@ -201,7 +201,6 @@ move_allocates_2(Alloc, [], Acc) ->
alloc_may_pass({set,_,_,{alloc,_,_}}) -> false;
alloc_may_pass({set,_,_,{set_tuple_element,_}}) -> false;
alloc_may_pass({set,_,_,put_list}) -> false;
-alloc_may_pass({set,_,_,{put_tuple,_}}) -> false;
alloc_may_pass({set,_,_,put}) -> false;
alloc_may_pass({set,_,_,_}) -> true.
diff --git a/lib/compiler/src/beam_bool.erl b/lib/compiler/src/beam_bool.erl
index dcc6ad4c7c..d9ea6f5a70 100644
--- a/lib/compiler/src/beam_bool.erl
+++ b/lib/compiler/src/beam_bool.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%
%%
%% Purpose: Optimizes booleans in guards.
@@ -631,10 +631,10 @@ fetch_reg(V, [{I,V}|_]) -> {x,I};
fetch_reg(V, [_|SRs]) -> fetch_reg(V, SRs).
live_regs(Regs) ->
- foldl(fun ({I,_}, _) -> I;
- ([], Max) -> Max end,
- -1, Regs)+1.
-
+ foldl(fun ({I,_}, _) ->
+ I
+ end, -1, Regs)+1.
+
%%%
%%% Convert a block to Static Single Assignment (SSA) form.
@@ -748,8 +748,7 @@ initialized_regs([{bs_context_to_binary,Src}|Is], Regs) ->
initialized_regs([{label,_},{func_info,_,_,Arity}|_], Regs) ->
InitRegs = free_vars_regs(Arity),
add_init_regs(InitRegs, Regs);
-initialized_regs([_|_], Regs) -> Regs;
-initialized_regs([], Regs) -> Regs.
+initialized_regs([_|_], Regs) -> Regs.
add_init_regs([{x,_}=X|T], Regs) ->
add_init_regs(T, ordsets:add_element(X, Regs));
diff --git a/lib/compiler/src/beam_dead.erl b/lib/compiler/src/beam_dead.erl
index 7b4cd814a2..bb93110176 100644
--- a/lib/compiler/src/beam_dead.erl
+++ b/lib/compiler/src/beam_dead.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%
%%
@@ -281,12 +281,12 @@ forward([{test,is_eq_exact,_,[Dst,Src]}=I,{move,Src,Dst}|Is], D, Lc, Acc) ->
forward([I|Is], D, Lc, Acc);
forward([{test,is_nil,_,[Dst]}=I,{move,nil,Dst}|Is], D, Lc, Acc) ->
forward([I|Is], D, Lc, Acc);
-forward([{test,is_eq_exact,_,[_,{atom,_}]}=I|Is], D, Lc, [{label,_}|_]=Acc) ->
+forward([{test,is_eq_exact,_,_}=I|Is], D, Lc, Acc) ->
case Is of
[{label,_}|_] -> forward(Is, D, Lc, [I|Acc]);
_ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc])
end;
-forward([{test,is_ne_exact,_,[_,{atom,_}]}=I|Is], D, Lc, [{label,_}|_]=Acc) ->
+forward([{test,is_ne_exact,_,_}=I|Is], D, Lc, Acc) ->
case Is of
[{label,_}|_] -> forward(Is, D, Lc, [I|Acc]);
_ -> forward(Is, D, Lc+1, [{label,Lc},I|Acc])
@@ -371,10 +371,10 @@ backward([{test,bs_start_match2,{f,To0},Live,[Src|_]=Info,Dst}|Is], D, Acc) ->
To = shortcut_bs_start_match(To0, Src, D),
I = {test,bs_start_match2,{f,To},Live,Info,Dst},
backward(Is, D, [I|Acc]);
-backward([{test,is_eq_exact=Op,{f,To0},[Reg,{atom,Val}]=Ops}|Is], D, Acc) ->
+backward([{test,is_eq_exact,{f,To0},[Reg,{atom,Val}]=Ops}|Is], D, Acc) ->
To1 = shortcut_bs_test(To0, Is, D),
To = shortcut_fail_label(To1, Reg, Val, D),
- I = {test,Op,{f,To},Ops},
+ I = combine_eqs(To, Ops, D, Acc),
backward(Is, D, [I|Acc]);
backward([{test,Op,{f,To0},Ops0}|Is], D, Acc) ->
To1 = shortcut_bs_test(To0, Is, D),
@@ -394,7 +394,10 @@ backward([{test,Op,{f,To0},Ops0}|Is], D, Acc) ->
_Code ->
To2
end,
- I = {test,Op,{f,To},Ops0},
+ I = case Op of
+ is_eq_exact -> combine_eqs(To, Ops0, D, Acc);
+ _ -> {test,Op,{f,To},Ops0}
+ end,
backward(Is, D, [I|Acc]);
backward([{test,Op,{f,To0},Live,Ops0,Dst}|Is], D, Acc) ->
To1 = shortcut_bs_test(To0, Is, D),
@@ -519,6 +522,41 @@ bif_to_test(Name, Args, Fail) ->
not_possible() -> throw(not_possible).
+%% combine_eqs(To, Operands, Acc) -> Instruction.
+%% Combine two is_eq_exact instructions or (an is_eq_exact
+%% instruction and a select_val instruction) to a select_val
+%% instruction if possible.
+%%
+%% Example:
+%%
+%% is_eq_exact F1 Reg Lit1 select_val Reg F2 [ Lit1 L1
+%% L1: . Lit2 L2 ]
+%% .
+%% . ==>
+%% .
+%% F1: is_eq_exact F2 Reg Lit2 F1: is_eq_exact F2 Reg Lit2
+%% L2: .... L2:
+%%
+combine_eqs(To, [Reg,{Type,_}=Lit1]=Ops, D, [{label,L1}|_])
+ when Type =:= atom; Type =:= integer ->
+ case beam_utils:code_at(To, D) of
+ [{test,is_eq_exact,{f,F2},[Reg,{Type,_}=Lit2]},
+ {label,L2}|_] when Lit1 =/= Lit2 ->
+ {select_val,Reg,{f,F2},{list,[Lit1,{f,L1},Lit2,{f,L2}]}};
+ [{select_val,Reg,{f,F2},{list,[{Type,_}|_]=List0}}|_] ->
+ List = remove_from_list(Lit1, List0),
+ {select_val,Reg,{f,F2},{list,[Lit1,{f,L1}|List]}};
+ _Is ->
+ {test,is_eq_exact,{f,To},Ops}
+ end;
+combine_eqs(To, Ops, _D, _Acc) ->
+ {test,is_eq_exact,{f,To},Ops}.
+
+remove_from_list(Lit, [Lit,{f,_}|T]) ->
+ T;
+remove_from_list(Lit, [Val,{f,_}=Fail|T]) ->
+ [Val,Fail|remove_from_list(Lit, T)];
+remove_from_list(_, []) -> [].
%% shortcut_bs_test(TargetLabel, [Instruction], D) -> TargetLabel'
%% Try to shortcut the failure label for a bit syntax matching.
diff --git a/lib/compiler/src/beam_disasm.erl b/lib/compiler/src/beam_disasm.erl
index c956f2f000..017ca129b0 100644
--- a/lib/compiler/src/beam_disasm.erl
+++ b/lib/compiler/src/beam_disasm.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%
%%=======================================================================
%% Notes:
@@ -621,8 +621,7 @@ resolve_names(Fun, Imports, Str, Lbls, Lambdas, Literals, M) ->
%%
%% New make_fun2/4 instruction added in August 2001 (R8).
-%% New put_literal/2 instruction added in Feb 2006 R11B-4.
-%% We handle them specially here to avoid adding an argument to
+%% We handle it specially here to avoid adding an argument to
%% the clause for every instruction.
%%
@@ -631,8 +630,6 @@ resolve_inst({make_fun2,Args}, _, _, _, Lambdas, _, M) ->
{OldIndex,{F,A,_Lbl,_Index,NumFree,OldUniq}} =
lists:keyfind(OldIndex, 1, Lambdas),
{make_fun2,{M,F,A},OldIndex,OldUniq,NumFree};
-resolve_inst({put_literal,[{u,Index},Dst]},_,_,_,_,Literals,_) ->
- {put_literal,{literal,gb_trees:get(Index, Literals)},Dst};
resolve_inst(Instr, Imports, Str, Lbls, _Lambdas, _Literals, _M) ->
%% io:format(?MODULE_STRING":resolve_inst ~p.~n", [Instr]),
resolve_inst(Instr, Imports, Str, Lbls).
@@ -1004,13 +1001,17 @@ resolve_inst({gc_bif2,Args},Imports,_,_) ->
[F,Live,Bif,A1,A2,Reg] = resolve_args(Args),
{extfunc,_Mod,BifName,_Arity} = lookup(Bif+1,Imports),
{gc_bif,BifName,F,Live,[A1,A2],Reg};
+%%
+%% New instruction in R14, gc_bif with 3 arguments
+%%
+resolve_inst({gc_bif3,Args},Imports,_,_) ->
+ [F,Live,Bif,A1,A2,A3,Reg] = resolve_args(Args),
+ {extfunc,_Mod,BifName,_Arity} = lookup(Bif+1,Imports),
+ {gc_bif,BifName,F,Live,[A1,A2,A3],Reg};
%%
%% New instructions for creating non-byte aligned binaries.
%%
-resolve_inst({bs_bits_to_bytes2,[_Arg2,_Arg3]=Args},_,_,_) ->
- [A2,A3] = resolve_args(Args),
- {bs_bits_to_bytes2,A2,A3};
resolve_inst({bs_final2,[X,Y]},_,_,_) ->
{bs_final2,X,Y};
@@ -1096,6 +1097,14 @@ resolve_inst({on_load,[]},_,_,_) ->
on_load;
%%
+%% R14A.
+%%
+resolve_inst({recv_mark,[Lbl]},_,_,_) ->
+ {recv_mark,Lbl};
+resolve_inst({recv_set,[Lbl]},_,_,_) ->
+ {recv_set,Lbl};
+
+%%
%% Catches instructions that are not yet handled.
%%
resolve_inst(X,_,_,_) -> ?exit({resolve_inst,X}).
diff --git a/lib/compiler/src/beam_peep.erl b/lib/compiler/src/beam_peep.erl
index d03ac4b1f4..f39fc50b95 100644
--- a/lib/compiler/src/beam_peep.erl
+++ b/lib/compiler/src/beam_peep.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%
%%
@@ -64,22 +64,7 @@ function({function,Name,Arity,CLabel,Is0}) ->
%% InEncoding =:= latin1, OutEncoding =:= unicode;
%% InEncoding =:= latin1, OutEncoding =:= utf8 ->
%%
-%% (2) Code like
-%%
-%% is_ne_exact Fail Reg Literal1
-%% is_ne_exact Fail Reg Literal2
-%% is_ne_exact Fail Reg Literal3
-%% is_eq_exact UltimateFail Reg Literal4
-%% Fail: ....
-%%
-%% can be rewritten to
-%%
-%% select_val Reg UltimateFail [ Literal1 Fail
-%% Literal2 Fail
-%% Literal3 Fail
-%% Literal4 Fail ]
-%%
-%% (3) A select_val/4 instruction that only verifies that
+%% (2) A select_val/4 instruction that only verifies that
%% its argument is either 'true' or 'false' can be
%% be replaced with an is_boolean/2 instruction. That is:
%%
@@ -132,7 +117,7 @@ peep([{test,Op,_,Ops}=I|Is], SeenTests0, Acc) ->
false ->
%% Remember that we have seen this test.
SeenTests = gb_sets:insert(Test, SeenTests0),
- make_select_val(I, Is, SeenTests, Acc)
+ peep(Is, SeenTests, [I|Acc])
end
end;
peep([{select_val,Src,Fail,
@@ -151,33 +136,6 @@ peep([I|Is], _, Acc) ->
peep(Is, gb_sets:empty(), [I|Acc]);
peep([], _, Acc) -> reverse(Acc).
-make_select_val({test,is_ne_exact,{f,Fail},[Val,Lit]}=I0,
- Is0, SeenTests, Acc) ->
- try
- Type = case Lit of
- {atom,_} -> atom;
- {integer,_} -> integer;
- _ -> throw(impossible)
- end,
- {I,Is} = make_select_val_1(Is0, Fail, Val, Type, [Lit,{f,Fail}]),
- peep([I|Is], SeenTests, Acc)
- catch
- impossible ->
- peep(Is0, SeenTests, [I0|Acc])
- end;
-make_select_val(I, Is, SeenTests, Acc) ->
- peep(Is, SeenTests, [I|Acc]).
-
-make_select_val_1([{test,is_ne_exact,{f,Fail},[Val,{Type,_}=Lit]}|Is],
- Fail, Val, Type, Acc) ->
- make_select_val_1(Is, Fail, Val, Type, [Lit,{f,Fail}|Acc]);
-make_select_val_1([{test,is_eq_exact,{f,UltimateFail},[Val,{Type,_}=Lit]} |
- [{label,Fail}|_]=Is], Fail, Val, Type, Acc) ->
- Choices = [Lit,{f,Fail}|Acc],
- I = {select_val,Val,{f,UltimateFail},{list,Choices}},
- {I,Is};
-make_select_val_1(_Is, _Fail, _Val, _Type, _Acc) -> throw(impossible).
-
kill_seen(Dst, Seen0) ->
gb_sets:from_ordset(kill_seen_1(gb_sets:to_list(Seen0), Dst)).
@@ -187,5 +145,3 @@ kill_seen_1([{_,Ops}=Test|T], Dst) ->
false -> [Test|kill_seen_1(T, Dst)]
end;
kill_seen_1([], _) -> [].
-
-
diff --git a/lib/compiler/src/beam_receive.erl b/lib/compiler/src/beam_receive.erl
new file mode 100644
index 0000000000..9ed44ad5d7
--- /dev/null
+++ b/lib/compiler/src/beam_receive.erl
@@ -0,0 +1,388 @@
+%%
+%% %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(beam_receive).
+-export([module/2]).
+-import(lists, [foldl/3,reverse/1,reverse/2]).
+
+%%%
+%%% In code such as:
+%%%
+%%% Ref = make_ref(), %Or erlang:monitor(process, Pid)
+%%% .
+%%% .
+%%% .
+%%% receive
+%%% {Ref,Reply} -> Reply
+%%% end.
+%%%
+%%% we know that none of the messages that exist in the message queue
+%%% before the call to make_ref/0 can be matched out in the receive
+%%% statement. Therefore we can avoid going through the entire message
+%%% queue if we introduce two new instructions (here written as
+%%% BIFs in pseudo-Erlang):
+%%%
+%%% recv_mark(SomeUniqInteger),
+%%% Ref = make_ref(),
+%%% .
+%%% .
+%%% .
+%%% recv_set(SomeUniqInteger),
+%%% receive
+%%% {Ref,Reply} -> Reply
+%%% end.
+%%%
+%%% The recv_mark/1 instruction will save the current position and
+%%% SomeUniqInteger in the process context. The recv_set
+%%% instruction will verify that SomeUniqInteger is still stored
+%%% in the process context. If it is, it will set the current pointer
+%%% for the message queue (the next message to be read out) to the
+%%% position that was saved by recv_mark/1.
+%%%
+%%% The remove_message instruction must be modified to invalidate
+%%% the information stored by the previous recv_mark/1, in case there
+%%% is another receive executed between the calls to recv_mark/1 and
+%%% recv_set/1.
+%%%
+%%% We use a reference to a label (i.e. a position in the loaded code)
+%%% as the SomeUniqInteger.
+%%%
+
+module({Mod,Exp,Attr,Fs0,Lc}, _Opts) ->
+ Fs = [function(F) || F <- Fs0],
+ Code = {Mod,Exp,Attr,Fs,Lc},
+ {ok,Code}.
+
+%%%
+%%% Local functions.
+%%%
+
+function({function,Name,Arity,Entry,Is}) ->
+ try
+ D = beam_utils:index_labels(Is),
+ {function,Name,Arity,Entry,opt(Is, D, [])}
+ catch
+ Class:Error ->
+ Stack = erlang:get_stacktrace(),
+ io:fwrite("Function: ~w/~w\n", [Name,Arity]),
+ erlang:raise(Class, Error, Stack)
+ end.
+
+opt([{call_ext,Arity,{extfunc,erlang,Name,Arity}}=I|Is0], D, Acc) ->
+ case creates_new_ref(Name, Arity) of
+ true ->
+ %% The call creates a brand new reference. Now
+ %% search for a receive statement in the same
+ %% function that will match against the reference.
+ case opt_recv(Is0, D) of
+ no ->
+ opt(Is0, D, [I|Acc]);
+ {yes,Is,Lbl} ->
+ opt(Is, D, [I,{recv_mark,{f,Lbl}}|Acc])
+ end;
+ false ->
+ opt(Is0, D, [I|Acc])
+ end;
+opt([I|Is], D, Acc) ->
+ opt(Is, D, [I|Acc]);
+opt([], _, Acc) ->
+ reverse(Acc).
+
+%% creates_new_ref(Name, Arity) -> true|false.
+%% Return 'true' if the BIF Name/Arity will create a new reference.
+creates_new_ref(monitor, 2) -> true;
+creates_new_ref(make_ref, 0) -> true;
+creates_new_ref(_, _) -> false.
+
+%% opt_recv([Instruction], LabelIndex) -> no|{yes,[Instruction]}
+%% Search for a receive statement that will only retrieve messages
+%% that contain the newly created reference (which is currently in {x,0}).
+opt_recv(Is, D) ->
+ R = regs_init_x0(),
+ L = gb_sets:empty(),
+ opt_recv(Is, D, R, L, []).
+
+opt_recv([{label,L}=Lbl,{loop_rec,{f,Fail},_}=Loop|Is], D, R0, _, Acc) ->
+ R = regs_kill_not_live(0, R0),
+ case regs_to_list(R) of
+ [{y,_}=RefReg] ->
+ %% We now have the new reference in the Y register RefReg
+ %% and the current instruction is the beginning of a
+ %% receive statement. We must now verify that only messages
+ %% that contain the reference will be matched.
+ case opt_ref_used(Is, RefReg, Fail, D) of
+ false ->
+ no;
+ true ->
+ RecvSet = {recv_set,{f,L}},
+ {yes,reverse(Acc, [RecvSet,Lbl,Loop|Is]),L}
+ end;
+ [] ->
+ no
+ end;
+opt_recv([I|Is], D, R0, L0, Acc) ->
+ {R,L} = opt_update_regs(I, R0, L0),
+ case regs_empty(R) of
+ true ->
+ %% The reference is no longer alive. There is no
+ %% point in continuing the search.
+ no;
+ false ->
+ opt_recv(Is, D, R, L, [I|Acc])
+ end.
+
+opt_update_regs({block,Bl}, R, L) ->
+ {opt_update_regs_bl(Bl, R),L};
+opt_update_regs({call,_,_}, R, L) ->
+ {regs_kill_not_live(0, R),L};
+opt_update_regs({call_ext,_,_}, R, L) ->
+ {regs_kill_not_live(0, R),L};
+opt_update_regs({call_fun,_}, R, L) ->
+ {regs_kill_not_live(0, R),L};
+opt_update_regs({kill,Y}, R, L) ->
+ {regs_kill([Y], R),L};
+opt_update_regs(send, R, L) ->
+ {regs_kill_not_live(0, R),L};
+opt_update_regs({'catch',_,{f,Lbl}}, R, L) ->
+ {R,gb_sets:add(Lbl, L)};
+opt_update_regs({catch_end,_}, R, L) ->
+ {R,L};
+opt_update_regs({label,Lbl}, R, L) ->
+ case gb_sets:is_member(Lbl, L) of
+ false ->
+ %% We can't allow arbitrary labels (since the receive
+ %% could be entered without first creating the reference).
+ {regs_init(),L};
+ true ->
+ %% A catch label for a previously seen catch instruction is OK.
+ {R,L}
+ end;
+opt_update_regs({try_end,_}, R, L) ->
+ {R,L};
+opt_update_regs(_I, _R, L) ->
+ %% Unrecognized instruction. Abort the search.
+ {regs_init(),L}.
+
+opt_update_regs_bl([{set,Ds,_,{alloc,Live,_}}|Is], Regs0) ->
+ Regs1 = regs_kill_not_live(Live, Regs0),
+ Regs = regs_kill(Ds, Regs1),
+ opt_update_regs_bl(Is, Regs);
+opt_update_regs_bl([{set,[Dst]=Ds,[Src],move}|Is], Regs0) ->
+ Regs1 = regs_kill(Ds, Regs0),
+ Regs = case regs_is_member(Src, Regs1) of
+ false -> Regs1;
+ true -> regs_add(Dst, Regs1)
+ end,
+ opt_update_regs_bl(Is, Regs);
+opt_update_regs_bl([{set,Ds,_,_}|Is], Regs0) ->
+ Regs = regs_kill(Ds, Regs0),
+ opt_update_regs_bl(Is, Regs);
+opt_update_regs_bl([], Regs) -> Regs.
+
+%% opt_ref_used([Instruction], RefRegister, FailLabel, LabelIndex) -> true|false
+%% Return 'true' if it is certain that only messages that contain the same
+%% reference as in RefRegister can be matched out. Otherwise return 'false'.
+%%
+%% Basically, we follow all possible paths through the receive statement.
+%% If all paths are safe, we return 'true'.
+%%
+%% A branch to FailLabel is safe, because it exits the receive statement
+%% and no further message may be matched out.
+%%
+%% If a path hits an comparision between RefRegister and part of the message,
+%% that path is safe (any messages that may be matched further down the
+%% path is guaranteed to contain the reference).
+%%
+%% Otherwise, if we hit a 'remove_message' instruction, we give up
+%% and return 'false' (the optimization is definitely unsafe). If
+%% we hit an unrecognized instruction, we also give up and return
+%% 'false' (the optimization may be unsafe).
+
+opt_ref_used(Is, RefReg, Fail, D) ->
+ Done = gb_sets:singleton(Fail),
+ Regs = regs_init_x0(),
+ try
+ opt_ref_used_1(Is, RefReg, D, Done, Regs),
+ true
+ catch
+ throw:not_used ->
+ false
+ end.
+
+%% This functions only returns if all paths through the receive
+%% statement are safe, and throws an 'not_used' term otherwise.
+opt_ref_used_1([{block,Bl}|Is], RefReg, D, Done, Regs0) ->
+ Regs = opt_ref_used_bl(Bl, Regs0),
+ opt_ref_used_1(Is, RefReg, D, Done, Regs);
+opt_ref_used_1([{test,is_eq_exact,{f,Fail},Args}|Is], RefReg, D, Done0, Regs) ->
+ Done = opt_ref_used_at(Fail, RefReg, D, Done0, Regs),
+ case is_ref_msg_comparison(Args, RefReg, Regs) of
+ false ->
+ opt_ref_used_1(Is, RefReg, D, Done, Regs);
+ true ->
+ %% The instructions that follow (Is) can only be executed
+ %% if the message contains the same reference as in RefReg.
+ Done
+ end;
+opt_ref_used_1([{test,is_ne_exact,{f,Fail},Args}|Is], RefReg, D, Done0, Regs) ->
+ Done = opt_ref_used_1(Is, RefReg, D, Done0, Regs),
+ case is_ref_msg_comparison(Args, RefReg, Regs) of
+ false ->
+ opt_ref_used_at(Fail, RefReg, D, Done, Regs);
+ true ->
+ Done
+ end;
+opt_ref_used_1([{test,_,{f,Fail},_}|Is], RefReg, D, Done0, Regs) ->
+ Done = opt_ref_used_at(Fail, RefReg, D, Done0, Regs),
+ opt_ref_used_1(Is, RefReg, D, Done, Regs);
+opt_ref_used_1([{select_tuple_arity,_,{f,Fail},{list,List}}|_], RefReg, D, Done, Regs) ->
+ Lbls = [F || {f,F} <- List] ++ [Fail],
+ opt_ref_used_in_all(Lbls, RefReg, D, Done, Regs);
+opt_ref_used_1([{select_val,_,{f,Fail},{list,List}}|_], RefReg, D, Done, Regs) ->
+ Lbls = [F || {f,F} <- List] ++ [Fail],
+ opt_ref_used_in_all(Lbls, RefReg, D, Done, Regs);
+opt_ref_used_1([{label,Lbl}|Is], RefReg, D, Done, Regs) ->
+ case gb_sets:is_member(Lbl, Done) of
+ true -> Done;
+ false -> opt_ref_used_1(Is, RefReg, D, Done, Regs)
+ end;
+opt_ref_used_1([{loop_rec_end,_}|_], _, _, Done, _) ->
+ Done;
+opt_ref_used_1([_I|_], _RefReg, _D, _Done, _Regs) ->
+ %% The optimization may be unsafe.
+ throw(not_used).
+
+%% is_ref_msg_comparison(Args, RefReg, RegisterSet) -> true|false.
+%% Return 'true' if Args denotes a comparison between the
+%% reference and message or part of the message.
+is_ref_msg_comparison([R,RefReg], RefReg, Regs) ->
+ regs_is_member(R, Regs);
+is_ref_msg_comparison([RefReg,R], RefReg, Regs) ->
+ regs_is_member(R, Regs);
+is_ref_msg_comparison([_,_], _, _) -> false.
+
+opt_ref_used_in_all([L|Ls], RefReg, D, Done0, Regs) ->
+ Done = opt_ref_used_at(L, RefReg, D, Done0, Regs),
+ opt_ref_used_in_all(Ls, RefReg, D, Done, Regs);
+opt_ref_used_in_all([], _, _, Done, _) -> Done.
+
+opt_ref_used_at(Fail, RefReg, D, Done0, Regs) ->
+ case gb_sets:is_member(Fail, Done0) of
+ true ->
+ Done0;
+ false ->
+ Is = beam_utils:code_at(Fail, D),
+ Done = opt_ref_used_1(Is, RefReg, D, Done0, Regs),
+ gb_sets:add(Fail, Done)
+ end.
+
+opt_ref_used_bl([{set,[],[],remove_message}|_], _) ->
+ %% We have proved that a message that does not depend on the
+ %% reference can be matched out.
+ throw(not_used);
+opt_ref_used_bl([{set,Ds,Ss,_}|Is], Regs0) ->
+ case regs_all_members(Ss, Regs0) of
+ false ->
+ %% The destination registers may be assigned values that
+ %% are not dependent on the message being matched.
+ Regs = regs_kill(Ds, Regs0),
+ opt_ref_used_bl(Is, Regs);
+ true ->
+ %% All the sources depend on the message directly or
+ %% indirectly.
+ Regs = regs_add_list(Ds, Regs0),
+ opt_ref_used_bl(Is, Regs)
+ end;
+opt_ref_used_bl([], Regs) -> Regs.
+
+%%%
+%%% Functions for keeping track of a set of registers.
+%%%
+
+%% regs_init() -> RegisterSet
+%% Return an empty set of registers.
+
+regs_init() ->
+ {0,0}.
+
+%% regs_init_x0() -> RegisterSet
+%% Return a set that only contains the {x,0} register.
+
+regs_init_x0() ->
+ {1 bsl 0,0}.
+
+%% regs_empty(Register) -> true|false
+%% Test whether the register set is empty.
+
+regs_empty(R) ->
+ R =:= {0,0}.
+
+%% regs_kill_not_live(Live, RegisterSet) -> RegisterSet'
+%% Kill all registers indicated not live by Live.
+
+regs_kill_not_live(Live, {Xregs,Yregs}) ->
+ {Xregs band ((1 bsl Live)-1),Yregs}.
+
+%% regs_kill([Register], RegisterSet) -> RegisterSet'
+%% Kill all registers mentioned in the list of registers.
+
+regs_kill([{x,N}|Rs], {Xregs,Yregs}) ->
+ regs_kill(Rs, {Xregs band (bnot (1 bsl N)),Yregs});
+regs_kill([{y,N}|Rs], {Xregs,Yregs}) ->
+ regs_kill(Rs, {Xregs,Yregs band (bnot (1 bsl N))});
+regs_kill([{fr,_}|Rs], Regs) ->
+ regs_kill(Rs, Regs);
+regs_kill([], Regs) -> Regs.
+
+regs_add_list(List, Regs) ->
+ foldl(fun(R, A) -> regs_add(R, A) end, Regs, List).
+
+%% regs_add(Register, RegisterSet) -> RegisterSet'
+%% Add a new register to the set of registers.
+
+regs_add({x,N}, {Xregs,Yregs}) ->
+ {Xregs bor (1 bsl N),Yregs};
+regs_add({y,N}, {Xregs,Yregs}) ->
+ {Xregs,Yregs bor (1 bsl N)}.
+
+%% regs_all_members([Register], RegisterSet) -> true|false
+%% Test whether all of the registers are part of the register set.
+
+regs_all_members([R|Rs], Regs) ->
+ regs_is_member(R, Regs) andalso regs_all_members(Rs, Regs);
+regs_all_members([], _) -> true.
+
+%% regs_is_member(Register, RegisterSet) -> true|false
+%% Test whether Register is part of the register set.
+
+regs_is_member({x,N}, {Regs,_}) -> Regs band (1 bsl N) =/= 0;
+regs_is_member({y,N}, {_,Regs}) -> Regs band (1 bsl N) =/= 0;
+regs_is_member(_, _) -> false.
+
+%% regs_to_list(RegisterSet) -> [Register]
+%% Convert the register set to an explicit list of registers.
+regs_to_list({Xregs,Yregs}) ->
+ regs_to_list_1(Xregs, 0, x, regs_to_list_1(Yregs, 0, y, [])).
+
+regs_to_list_1(0, _, _, Acc) ->
+ Acc;
+regs_to_list_1(Regs, N, Tag, Acc) when (Regs band 1) =:= 1 ->
+ regs_to_list_1(Regs bsr 1, N+1, Tag, [{Tag,N}|Acc]);
+regs_to_list_1(Regs, N, Tag, Acc) ->
+ regs_to_list_1(Regs bsr 1, N+1, Tag, Acc).
diff --git a/lib/compiler/src/beam_type.erl b/lib/compiler/src/beam_type.erl
index 3729ccb0da..f83f73b224 100644
--- a/lib/compiler/src/beam_type.erl
+++ b/lib/compiler/src/beam_type.erl
@@ -76,9 +76,6 @@ simplify_basic_1([{set,[D],[{integer,Index},Reg],{bif,element,_}}=I0|Is], Ts0, A
end,
Ts = update(I, Ts0),
simplify_basic_1(Is, Ts, [I|Acc]);
-simplify_basic_1([{set,[_],[_],{bif,_,{f,0}}}=I|Is], Ts0, Acc) ->
- Ts = update(I, Ts0),
- simplify_basic_1(Is, Ts, [I|Acc]);
simplify_basic_1([{set,[D],[TupleReg],{get_tuple_element,0}}=I|Is0], Ts0, Acc) ->
case tdb_find(TupleReg, Ts0) of
{tuple,_,[Contents]} ->
@@ -118,7 +115,6 @@ simplify_basic_1([{test,is_record,_,[R,{atom,_}=Tag,{integer,Arity}]}=I|Is], Ts0
Ts = update(I, Ts0),
simplify_basic_1(Is, Ts, [I|Acc])
end;
-
simplify_basic_1([I|Is], Ts0, Acc) ->
Ts = update(I, Ts0),
simplify_basic_1(Is, Ts, [I|Acc]);
diff --git a/lib/compiler/src/beam_utils.erl b/lib/compiler/src/beam_utils.erl
index ac249e6672..761d4ffec0 100644
--- a/lib/compiler/src/beam_utils.erl
+++ b/lib/compiler/src/beam_utils.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%
%%
%% Purpose : Common utilities used by several optimization passes.
@@ -424,12 +424,6 @@ check_liveness(R, [{bs_add,{f,0},Ss,D}|Is], St) ->
false when R =:= D -> {killed,St};
false -> check_liveness(R, Is, St)
end;
-check_liveness(R, [{bs_bits_to_bytes2,Src,Dst}|Is], St) ->
- case R of
- Src -> {used,St};
- Dst -> {killed,St};
- _ -> check_liveness(R, Is, St)
- end;
check_liveness(R, [{bs_put_binary,{f,0},Sz,_,_,Src}|Is], St) ->
case member(R, [Sz,Src]) of
true -> {used,St};
diff --git a/lib/compiler/src/beam_validator.erl b/lib/compiler/src/beam_validator.erl
index 1fd61831e0..f3a2b01e04 100644
--- a/lib/compiler/src/beam_validator.erl
+++ b/lib/compiler/src/beam_validator.erl
@@ -18,6 +18,8 @@
-module(beam_validator).
+-compile({no_auto_import,[min/2]}).
+
-export([file/1, files/1]).
%% Interface for compiler.
@@ -416,6 +418,11 @@ valfun_1({put,Src}, Vst) ->
valfun_1({put_string,Sz,_,Dst}, Vst0) when is_integer(Sz) ->
Vst = eat_heap(2*Sz, Vst0),
set_type_reg(cons, Dst, Vst);
+%% Instructions for optimization of selective receives.
+valfun_1({recv_mark,{f,Fail}}, Vst) when is_integer(Fail) ->
+ Vst;
+valfun_1({recv_set,{f,Fail}}, Vst) when is_integer(Fail) ->
+ Vst;
%% Misc.
valfun_1({'%live',Live}, Vst) ->
verify_live(Live, Vst),
@@ -752,9 +759,6 @@ valfun_4({bs_utf8_size,{f,Fail},A,Dst}, Vst) ->
valfun_4({bs_utf16_size,{f,Fail},A,Dst}, Vst) ->
assert_term(A, Vst),
set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst));
-valfun_4({bs_bits_to_bytes2,Src,Dst}, Vst) ->
- assert_term(Src, Vst),
- set_type_reg({integer,[]}, Dst, Vst);
valfun_4({bs_bits_to_bytes,{f,Fail},Src,Dst}, Vst) ->
assert_term(Src, Vst),
set_type_reg({integer,[]}, Dst, branch_state(Fail, Vst));
diff --git a/lib/compiler/src/cerl.erl b/lib/compiler/src/cerl.erl
index 74fc0878cf..d1fd9d40e2 100644
--- a/lib/compiler/src/cerl.erl
+++ b/lib/compiler/src/cerl.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%
%% =====================================================================
@@ -122,6 +122,9 @@
bitstr_bitsize/1, bitstr_unit/1, bitstr_type/1,
bitstr_flags/1]).
+-export_type([c_binary/0, c_call/0, c_clause/0, c_cons/0, c_fun/0, c_literal/0,
+ c_module/0, c_tuple/0, c_values/0, c_var/0, cerl/0, var_name/0]).
+
%%
%% needed by the include file below -- do not move
%%
diff --git a/lib/compiler/src/cerl_inline.erl b/lib/compiler/src/cerl_inline.erl
index 6d7eca0113..c15103999f 100644
--- a/lib/compiler/src/cerl_inline.erl
+++ b/lib/compiler/src/cerl_inline.erl
@@ -65,7 +65,6 @@
try_evars/1, try_handler/1, tuple_es/1, tuple_arity/1,
type/1, values_es/1, var_name/1]).
--import(erlang, [max/2]).
-import(lists, [foldl/3, foldr/3, mapfoldl/3, reverse/1]).
%%
@@ -201,9 +200,9 @@ start(Reply, Tree, Ctxt, Opts) ->
false ->
ok
end,
- Size = max(1, proplists:get_value(inline_size, Opts)),
- Effort = max(1, proplists:get_value(inline_effort, Opts)),
- Unroll = max(1, proplists:get_value(inline_unroll, Opts)),
+ Size = erlang:max(1, proplists:get_value(inline_size, Opts)),
+ Effort = erlang:max(1, proplists:get_value(inline_effort, Opts)),
+ Unroll = erlang:max(1, proplists:get_value(inline_unroll, Opts)),
case proplists:get_bool(verbose, Opts) of
true ->
io:fwrite("Inlining: inline_size=~w inline_effort=~w\n",
diff --git a/lib/compiler/src/cerl_trees.erl b/lib/compiler/src/cerl_trees.erl
index 7a2057713e..1e3755025f 100644
--- a/lib/compiler/src/cerl_trees.erl
+++ b/lib/compiler/src/cerl_trees.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%
%% @doc Basic functions on Core Erlang abstract syntax trees.
@@ -73,14 +73,12 @@ depth(T) ->
[] ->
0;
Gs ->
- 1 + lists:foldl(fun (G, A) -> max(depth_1(G), A) end, 0, Gs)
+ 1 + lists:foldl(fun (G, A) -> erlang:max(depth_1(G), A) end, 0, Gs)
end.
depth_1(Ts) ->
- lists:foldl(fun (T, A) -> max(depth(T), A) end, 0, Ts).
+ lists:foldl(fun (T, A) -> erlang:max(depth(T), A) end, 0, Ts).
-max(X, Y) when X > Y -> X;
-max(_, Y) -> Y.
%% @spec size(Tree::cerl()) -> integer()
diff --git a/lib/compiler/src/compile.erl b/lib/compiler/src/compile.erl
index 5017fd2c23..4642fb68b3 100644
--- a/lib/compiler/src/compile.erl
+++ b/lib/compiler/src/compile.erl
@@ -29,6 +29,8 @@
%% Erlc interface.
-export([compile/3,compile_beam/3,compile_asm/3,compile_core/3]).
+-export_type([option/0]).
+
-include("erl_compile.hrl").
-include("core_parse.hrl").
@@ -162,6 +164,10 @@ expand_opt(report, Os) ->
[report_errors,report_warnings|Os];
expand_opt(return, Os) ->
[return_errors,return_warnings|Os];
+expand_opt(r12, Os) ->
+ [no_recv_opt|Os];
+expand_opt(r13, Os) ->
+ [no_recv_opt|Os];
expand_opt({debug_info_key,_}=O, Os) ->
[encrypt_debug_info,O|Os];
expand_opt(no_float_opt, Os) ->
@@ -290,15 +296,6 @@ fold_comp([{Name,Pass}|Ps], Run, St0) ->
end;
fold_comp([], _Run, St) -> {ok,St}.
-os_process_size() ->
- case os:type() of
- {unix, sunos} ->
- Size = os:cmd("ps -o vsz -p " ++ os:getpid() ++ " | tail -1"),
- list_to_integer(lib:nonl(Size));
- _ ->
- 0
- end.
-
run_tc({Name,Fun}, St) ->
Before0 = statistics(runtime),
Val = (catch Fun(St)),
@@ -307,9 +304,8 @@ run_tc({Name,Fun}, St) ->
{After_c, _} = After0,
Mem0 = erts_debug:flat_size(Val)*erlang:system_info(wordsize),
Mem = lists:flatten(io_lib:format("~.1f kB", [Mem0/1024])),
- Sz = lists:flatten(io_lib:format("~.1f MB", [os_process_size()/1024])),
- io:format(" ~-30s: ~10.2f s ~12s ~10s\n",
- [Name,(After_c-Before_c) / 1000,Mem,Sz]),
+ io:format(" ~-30s: ~10.2f s ~12s\n",
+ [Name,(After_c-Before_c) / 1000,Mem]),
Val.
comp_ret_ok(#compile{code=Code,warnings=Warn0,module=Mod,options=Opts}=St) ->
@@ -621,6 +617,8 @@ asm_passes() ->
{iff,dclean,{listing,"clean"}},
{unless,no_bsm_opt,{pass,beam_bsm}},
{iff,dbsm,{listing,"bsm"}},
+ {unless,no_recv_opt,{pass,beam_receive}},
+ {iff,drecv,{listing,"recv"}},
{unless,no_stack_trimming,{pass,beam_trim}},
{iff,dtrim,{listing,"trim"}},
{pass,beam_flatten}]},
@@ -904,13 +902,8 @@ expand_module(#compile{code=Code,options=Opts0}=St0) ->
{ok,St0#compile{module=Mod,options=Opts,code={Mod,Exp,Forms}}}.
core_module(#compile{code=Code0,options=Opts}=St) ->
- case v3_core:module(Code0, Opts) of
- {ok,Code,Ws} ->
- {ok,St#compile{code=Code,warnings=St#compile.warnings ++ Ws}};
- {error,Es,Ws} ->
- {error,St#compile{warnings=St#compile.warnings ++ Ws,
- errors=St#compile.errors ++ Es}}
- end.
+ {ok,Code,Ws} = v3_core:module(Code0, Opts),
+ {ok,St#compile{code=Code,warnings=St#compile.warnings ++ Ws}}.
core_fold_module(#compile{code=Code0,options=Opts,warnings=Warns}=St) ->
{ok,Code,Ws} = sys_core_fold:module(Code0, Opts),
diff --git a/lib/compiler/src/compiler.app.src b/lib/compiler/src/compiler.app.src
index b0311365c4..4ac879c9a4 100644
--- a/lib/compiler/src/compiler.app.src
+++ b/lib/compiler/src/compiler.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%
{application, compiler,
@@ -33,6 +33,7 @@
beam_listing,
beam_opcodes,
beam_peep,
+ beam_receive,
beam_trim,
beam_type,
beam_utils,
diff --git a/lib/compiler/src/erl_bifs.erl b/lib/compiler/src/erl_bifs.erl
index e87bb276de..f8128702dd 100644
--- a/lib/compiler/src/erl_bifs.erl
+++ b/lib/compiler/src/erl_bifs.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%
%%
%% Purpose: Information about the Erlang built-in functions.
@@ -65,6 +65,8 @@ is_pure(erlang, 'xor', 2) -> true;
is_pure(erlang, abs, 1) -> true;
is_pure(erlang, atom_to_binary, 2) -> true;
is_pure(erlang, atom_to_list, 1) -> true;
+is_pure(erlang, binary_part, 2) -> true;
+is_pure(erlang, binary_part, 3) -> true;
is_pure(erlang, binary_to_atom, 2) -> true;
is_pure(erlang, binary_to_list, 1) -> true;
is_pure(erlang, binary_to_list, 3) -> true;
diff --git a/lib/compiler/src/genop.tab b/lib/compiler/src/genop.tab
index 47e6e72402..63527bda8f 100644
--- a/lib/compiler/src/genop.tab
+++ b/lib/compiler/src/genop.tab
@@ -208,7 +208,7 @@ BEAM_FORMAT_NUMBER=0
# New instructions in R10B.
109: bs_init2/6
-110: bs_bits_to_bytes/3
+110: -bs_bits_to_bytes/3
111: bs_add/5
112: apply/1
113: apply_last/2
@@ -274,3 +274,9 @@ BEAM_FORMAT_NUMBER=0
# R13B03
149: on_load/0
+
+# R14A
+
+150: recv_mark/1
+151: recv_set/1
+152: gc_bif3/7
diff --git a/lib/compiler/src/rec_env.erl b/lib/compiler/src/rec_env.erl
index 9b73e08ad8..77005a6f9d 100644
--- a/lib/compiler/src/rec_env.erl
+++ b/lib/compiler/src/rec_env.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%
%%
%% @author Richard Carlsson <[email protected]>
@@ -32,6 +32,8 @@
get/2, is_defined/2, is_empty/1, keys/1, lookup/2, new_key/1,
new_key/2, new_keys/2, new_keys/3, size/1, to_list/1]).
+-export_type([environment/0]).
+
-import(erlang, [max/2]).
-ifdef(DEBUG).
diff --git a/lib/compiler/src/sys_core_fold.erl b/lib/compiler/src/sys_core_fold.erl
index 6202f07479..96015fbe58 100644
--- a/lib/compiler/src/sys_core_fold.erl
+++ b/lib/compiler/src/sys_core_fold.erl
@@ -1038,6 +1038,8 @@ fold_non_lit_args(Call, lists, append, [Arg1,Arg2], _) ->
eval_append(Call, Arg1, Arg2);
fold_non_lit_args(Call, erlang, setelement, [Arg1,Arg2,Arg3], _) ->
eval_setelement(Call, Arg1, Arg2, Arg3);
+fold_non_lit_args(Call, erlang, is_record, [Arg1,Arg2,Arg3], Sub) ->
+ eval_is_record(Call, Arg1, Arg2, Arg3, Sub);
fold_non_lit_args(Call, erlang, N, Args, Sub) ->
NumArgs = length(Args),
case erl_internal:comp_op(N, NumArgs) of
@@ -1194,19 +1196,22 @@ eval_element(Call, #c_literal{val=Pos}, #c_tuple{es=Es}, _Types) when is_integer
true ->
eval_failure(Call, badarg)
end;
-%% eval_element(Call, #c_literal{val=Pos}, #c_var{name=V}, Types)
-%% when is_integer(Pos) ->
-%% case orddict:find(V, Types#sub.t) of
-%% {ok,#c_tuple{es=Elements}} ->
-%% if
-%% 1 =< Pos, Pos =< length(Elements) ->
-%% lists:nth(Pos, Elements);
-%% true ->
-%% eval_failure(Call, badarg)
-%% end;
-%% error ->
-%% Call
-%% end;
+eval_element(Call, #c_literal{val=Pos}, #c_var{name=V}, Types)
+ when is_integer(Pos) ->
+ case orddict:find(V, Types#sub.t) of
+ {ok,#c_tuple{es=Elements}} ->
+ if
+ 1 =< Pos, Pos =< length(Elements) ->
+ case lists:nth(Pos, Elements) of
+ #c_alias{var=Alias} -> Alias;
+ Res -> Res
+ end;
+ true ->
+ eval_failure(Call, badarg)
+ end;
+ error ->
+ Call
+ end;
eval_element(Call, Pos, Tuple, _Types) ->
case is_not_integer(Pos) orelse is_not_tuple(Tuple) of
true ->
@@ -1215,6 +1220,20 @@ eval_element(Call, Pos, Tuple, _Types) ->
Call
end.
+%% eval_is_record(Call, Var, Tag, Size, Types) -> Val.
+%% Evaluates is_record/3 using type information.
+%%
+eval_is_record(Call, #c_var{name=V}, #c_literal{val=NeededTag}=Lit,
+ #c_literal{val=Size}, Types) ->
+ case orddict:find(V, Types#sub.t) of
+ {ok,#c_tuple{es=[#c_literal{val=Tag}|_]=Es}} ->
+ Lit#c_literal{val=Tag =:= NeededTag andalso
+ length(Es) =:= Size};
+ _ ->
+ Call
+ end;
+eval_is_record(Call, _, _, _, _) -> Call.
+
%% is_not_integer(Core) -> true | false.
%% Returns true if Core is definitely not an integer.
diff --git a/lib/compiler/src/sys_pre_expand.erl b/lib/compiler/src/sys_pre_expand.erl
index f80d03dfac..480954adac 100644
--- a/lib/compiler/src/sys_pre_expand.erl
+++ b/lib/compiler/src/sys_pre_expand.erl
@@ -403,16 +403,21 @@ expr({'fun',Line,Body}, St) ->
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},As},St1};
- false ->
- case imported(N, Ar, St1) of
- {yes,Mod} ->
- {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1};
- no ->
- {{call,Line,Atom,As},St1}
- end
+ case defined(N,Ar,St1) of
+ true ->
+ {{call,Line,Atom,As},St1};
+ _ ->
+ case imported(N, Ar, St1) of
+ {yes,Mod} ->
+ {{call,Line,{remote,La,{atom,La,Mod},Atom},As},St1};
+ no ->
+ case erl_internal:bif(N, Ar) of
+ true ->
+ {{call,Line,{remote,La,{atom,La,erlang},Atom},As},St1};
+ false -> %% This should have been handled by erl_lint
+ {{call,Line,Atom,As},St1}
+ end
+ end
end;
expr({call,Line,{record_field,_,_,_}=M,As0}, St0) ->
expr({call,Line,expand_package(M, St0),As0}, St0);
@@ -685,3 +690,6 @@ imported(F, A, St) ->
{ok,Mod} -> {yes,Mod};
error -> no
end.
+
+defined(F, A, St) ->
+ ordsets:is_element({F,A}, St#expand.defined).
diff --git a/lib/compiler/src/v3_core.erl b/lib/compiler/src/v3_core.erl
index b2f0ac75c7..f6bb45787c 100644
--- a/lib/compiler/src/v3_core.erl
+++ b/lib/compiler/src/v3_core.erl
@@ -122,7 +122,6 @@
| iclause() | ifun() | iletrec() | imatch() | iprimop()
| iprotect() | ireceive1() | ireceive2() | iset() | itry().
--type error() :: {file:filename(), [{integer(), module(), term()}]}.
-type warning() :: {file:filename(), [{integer(), module(), term()}]}.
-record(core, {vcount=0 :: non_neg_integer(), %Variable counter
@@ -130,7 +129,6 @@
in_guard=false :: boolean(), %In guard or not.
wanted=true :: boolean(), %Result wanted or not.
opts :: [compile:option()], %Options.
- es=[] :: [error()], %Errors.
ws=[] :: [warning()], %Warnings.
file=[{file,""}]}). %File
@@ -141,46 +139,41 @@
| {attribute, integer(), attribute(), _}.
-spec module({module(), [fa()], [form()]}, [compile:option()]) ->
- {'ok',cerl:c_module(),[warning()]} | {'error',[error()],[warning()]}.
+ {'ok',cerl:c_module(),[warning()]}.
module({Mod,Exp,Forms}, Opts) ->
Cexp = map(fun ({_N,_A} = NA) -> #c_var{name=NA} end, Exp),
- {Kfs0,As0,Es,Ws,_File} = foldl(fun (F, Acc) ->
- form(F, Acc, Opts)
- end, {[],[],[],[],[]}, Forms),
+ {Kfs0,As0,Ws,_File} = foldl(fun (F, Acc) ->
+ form(F, Acc, Opts)
+ end, {[],[],[],[]}, Forms),
Kfs = reverse(Kfs0),
As = reverse(As0),
- case Es of
- [] ->
- {ok,#c_module{name=#c_literal{val=Mod},exports=Cexp,attrs=As,defs=Kfs},Ws};
- _ ->
- {error,Es,Ws}
- end.
+ {ok,#c_module{name=#c_literal{val=Mod},exports=Cexp,attrs=As,defs=Kfs},Ws}.
-form({function,_,_,_,_}=F0, {Fs,As,Es0,Ws0,File}, Opts) ->
- {F,Es,Ws} = function(F0, Es0, Ws0, File, Opts),
- {[F|Fs],As,Es,Ws,File};
-form({attribute,_,file,{File,_Line}}, {Fs,As,Es,Ws,_}, _Opts) ->
- {Fs,As,Es,Ws,File};
-form({attribute,_,_,_}=F, {Fs,As,Es,Ws,File}, _Opts) ->
- {Fs,[attribute(F)|As],Es,Ws,File}.
+form({function,_,_,_,_}=F0, {Fs,As,Ws0,File}, Opts) ->
+ {F,Ws} = function(F0, Ws0, File, Opts),
+ {[F|Fs],As,Ws,File};
+form({attribute,_,file,{File,_Line}}, {Fs,As,Ws,_}, _Opts) ->
+ {Fs,As,Ws,File};
+form({attribute,_,_,_}=F, {Fs,As,Ws,File}, _Opts) ->
+ {Fs,[attribute(F)|As],Ws,File}.
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) ->
+function({function,_,Name,Arity,Cs0}, Ws0, File, Opts) ->
%%ok = io:fwrite("~p - ", [{Name,Arity}]),
- St0 = #core{vcount=0,opts=Opts,es=Es0,ws=Ws0,file=[{file,File}]},
+ St0 = #core{vcount=0,opts=Opts,ws=Ws0,file=[{file,File}]},
{B0,St1} = body(Cs0, Name, Arity, St0),
%%ok = io:fwrite("1", []),
%%ok = io:fwrite("~w:~p~n", [?LINE,B0]),
{B1,St2} = ubody(B0, St1),
%%ok = io:fwrite("2", []),
%%ok = io:fwrite("~w:~p~n", [?LINE,B1]),
- {B2,#core{es=Es,ws=Ws}} = cbody(B1, St2),
+ {B2,#core{ws=Ws}} = cbody(B1, St2),
%%ok = io:fwrite("3~n", []),
%%ok = io:fwrite("~w:~p~n", [?LINE,B2]),
- {{#c_var{name={Name,Arity}},B2},Es,Ws}.
+ {{#c_var{name={Name,Arity}},B2},Ws}.
body(Cs0, Name, Arity, St0) ->
Anno = lineno_anno(element(2, hd(Cs0)), St0),
@@ -2096,20 +2089,12 @@ is_simple(#c_literal{}) -> true;
is_simple(#c_cons{hd=H,tl=T}) ->
is_simple(H) andalso is_simple(T);
is_simple(#c_tuple{es=Es}) -> is_simple_list(Es);
-is_simple(#c_binary{segments=Es}) -> is_simp_bin(Es);
is_simple(_) -> false.
-spec is_simple_list([cerl:cerl()]) -> boolean().
is_simple_list(Es) -> lists:all(fun is_simple/1, Es).
--spec is_simp_bin([cerl:cerl()]) -> boolean().
-
-is_simp_bin(Es) ->
- lists:all(fun (#c_bitstr{val=E,size=S}) ->
- is_simple(E) andalso is_simple(S)
- end, Es).
-
%%%
%%% Handling of warnings.
%%%
diff --git a/lib/compiler/src/v3_kernel.erl b/lib/compiler/src/v3_kernel.erl
index 974c64a8bc..fbe4d8617e 100644
--- a/lib/compiler/src/v3_kernel.erl
+++ b/lib/compiler/src/v3_kernel.erl
@@ -128,14 +128,27 @@ copy_anno(Kdst, Ksrc) ->
{'ok', #k_mdef{}, [warning()]}.
module(#c_module{anno=A,name=M,exports=Es,attrs=As,defs=Fs}, _Options) ->
+ Kas = attributes(As),
+ Kes = map(fun (#c_var{name={_,_}=Fname}) -> Fname end, Es),
St0 = #kern{lit=dict:new()},
{Kfs,St} = mapfoldl(fun function/2, St0, Fs),
- Kes = map(fun (#c_var{name={_,_}=Fname}) -> Fname end, Es),
- Kas = map(fun ({#c_literal{val=N},V}) ->
- {N,core_lib:literal_value(V)} end, As),
{ok,#k_mdef{anno=A,name=M#c_literal.val,exports=Kes,attributes=Kas,
body=Kfs ++ St#kern.funs},lists:sort(St#kern.ws)}.
+attributes([{#c_literal{val=Name},Val}|As]) ->
+ case include_attribute(Name) of
+ false ->
+ attributes(As);
+ true ->
+ [{Name,core_lib:literal_value(Val)}|attributes(As)]
+ end;
+attributes([]) -> [].
+
+include_attribute(type) -> false;
+include_attribute(spec) -> false;
+include_attribute(opaque) -> false;
+include_attribute(_) -> true.
+
function({#c_var{name={F,Arity}=FA},Body}, St0) ->
try
St1 = St0#kern{func=FA,ff=undefined,vcount=0,fcount=0,ds=sets:new()},
diff --git a/lib/compiler/src/v3_life.erl b/lib/compiler/src/v3_life.erl
index 9fda37530b..a7a4d4dc91 100644
--- a/lib/compiler/src/v3_life.erl
+++ b/lib/compiler/src/v3_life.erl
@@ -361,8 +361,6 @@ match_fail(#k_literal{anno=Anno,val={Atom,Val}}, I, A) when is_atom(Atom) ->
match_fail(#k_tuple{anno=Anno,es=[#k_atom{val=Atom},#k_literal{val=Val}]}, I, A);
match_fail(#k_literal{anno=Anno,val={Atom}}, I, A) when is_atom(Atom) ->
match_fail(#k_tuple{anno=Anno,es=[#k_atom{val=Atom}]}, I, A);
-match_fail(#k_literal{anno=Anno,val=Atom}, I, A) when is_atom(Atom) ->
- match_fail(#k_atom{anno=Anno,val=Atom}, I, A);
match_fail(#k_tuple{es=[#k_atom{val=function_clause}|As]}, I, A) ->
#l{ke={match_fail,{function_clause,literal_list(As, [])}},i=I,a=A};
match_fail(#k_tuple{es=[#k_atom{val=badmatch},Val]}, I, A) ->
diff --git a/lib/compiler/test/andor_SUITE.erl b/lib/compiler/test/andor_SUITE.erl
index a460d54239..84cfd16e60 100644
--- a/lib/compiler/test/andor_SUITE.erl
+++ b/lib/compiler/test/andor_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(andor_SUITE).
@@ -141,6 +141,10 @@ t_and_or(Config) when is_list(Config) ->
ok.
+-define(GUARD(E), if E -> true;
+ true -> false
+ end).
+
t_andalso(Config) when is_list(Config) ->
Bs = [true,false],
Ps = [{X,Y} || X <- Bs, Y <- Bs],
@@ -151,6 +155,11 @@ t_andalso(Config) when is_list(Config) ->
?line false = false andalso true,
?line false = false andalso false,
+ ?line true = ?GUARD(true andalso true),
+ ?line false = ?GUARD(true andalso false),
+ ?line false = ?GUARD(false andalso true),
+ ?line false = ?GUARD(false andalso false),
+
?line false = false andalso glurf,
?line false = false andalso exit(exit_now),
@@ -176,6 +185,11 @@ t_orelse(Config) when is_list(Config) ->
?line true = false orelse true,
?line false = false orelse false,
+ ?line true = ?GUARD(true orelse true),
+ ?line true = ?GUARD(true orelse false),
+ ?line true = ?GUARD(false orelse true),
+ ?line false = ?GUARD(false orelse false),
+
?line true = true orelse glurf,
?line true = true orelse exit(exit_now),
diff --git a/lib/compiler/test/bs_match_SUITE.erl b/lib/compiler/test/bs_match_SUITE.erl
index 75b6f801e7..caaa587006 100644
--- a/lib/compiler/test/bs_match_SUITE.erl
+++ b/lib/compiler/test/bs_match_SUITE.erl
@@ -30,7 +30,8 @@
multiple_uses/1,zero_label/1,followed_by_catch/1,
matching_meets_construction/1,simon/1,matching_and_andalso/1,
otp_7188/1,otp_7233/1,otp_7240/1,otp_7498/1,
- match_string/1,zero_width/1,bad_size/1,haystack/1]).
+ match_string/1,zero_width/1,bad_size/1,haystack/1,
+ cover_beam_bool/1]).
-export([coverage_id/1]).
@@ -45,7 +46,7 @@ all(suite) ->
wfbm,degenerated_match,bs_sum,coverage,multiple_uses,zero_label,
followed_by_catch,matching_meets_construction,simon,matching_and_andalso,
otp_7188,otp_7233,otp_7240,otp_7498,match_string,zero_width,bad_size,
- haystack].
+ haystack,cover_beam_bool].
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(1)),
@@ -985,6 +986,25 @@ fc(_, Args, {'EXIT',{{case_clause,ActualArgs},_}})
when ?MODULE =:= bs_match_inline_SUITE ->
Args = tuple_to_list(ActualArgs).
+%% Cover the clause handling bs_context to binary in
+%% beam_block:initialized_regs/2.
+cover_beam_bool(Config) when is_list(Config) ->
+ ?line ok = do_cover_beam_bool(<<>>, 3),
+ ?line <<19>> = do_cover_beam_bool(<<19>>, 2),
+ ?line <<42>> = do_cover_beam_bool(<<42>>, 1),
+ ?line <<17>> = do_cover_beam_bool(<<13,17>>, 0),
+ ok.
+
+do_cover_beam_bool(Bin, X) when X > 0 ->
+ if
+ X =:= 1; X =:= 2 ->
+ Bin;
+ true ->
+ ok
+ end;
+do_cover_beam_bool(<<_,Bin/binary>>, X) ->
+ do_cover_beam_bool(Bin, X+1).
+
check(F, R) ->
R = F().
diff --git a/lib/compiler/test/compile_SUITE.erl b/lib/compiler/test/compile_SUITE.erl
index 7c3990a855..e1cc5dafb5 100644
--- a/lib/compiler/test/compile_SUITE.erl
+++ b/lib/compiler/test/compile_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(compile_SUITE).
@@ -625,7 +625,7 @@ core(Config) when is_list(Config) ->
{raw_abstract_v1,Abstr}}]}} =
beam_lib:chunks(Beam, [abstract_code]),
{Mod,Abstr} end || Beam <- TestBeams],
- ?line Res = p_run(fun(F) -> do_core(F, Outdir) end, Abstr),
+ ?line Res = test_lib:p_run(fun(F) -> do_core(F, Outdir) end, Abstr),
?line test_server:timetrap_cancel(Dog),
Res.
@@ -661,7 +661,7 @@ asm(Config) when is_list(Config) ->
?line Wc = filename:join(filename:dirname(code:which(?MODULE)), "*.beam"),
?line TestBeams = filelib:wildcard(Wc),
- ?line Res = p_run(fun(F) -> do_asm(F, Outdir) end, TestBeams),
+ ?line Res = test_lib:p_run(fun(F) -> do_asm(F, Outdir) end, TestBeams),
?line test_server:timetrap_cancel(Dog),
Res.
@@ -688,35 +688,3 @@ do_asm(Beam, Outdir) ->
[M,Class,Error,erlang:get_stacktrace()]),
error
end.
-
-%% p_run(fun() -> ok|error, List) -> ok
-%% Will fail the test case if there were any errors.
-
-p_run(Test, List) ->
- N = erlang:system_info(schedulers) + 1,
- p_run_loop(Test, List, N, [], 0, 0).
-
-p_run_loop(_, [], _, [], Errors, Ws) ->
- case Errors of
- 0 ->
- case Ws of
- 0 -> ok;
- 1 -> {comment,"1 core_lint failure"};
- N -> {comment,integer_to_list(N)++" core_lint failures"}
- end;
- N -> ?t:fail({N,errors})
- end;
-p_run_loop(Test, [H|T], N, Refs, Errors, Ws) when length(Refs) < N ->
- {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end),
- p_run_loop(Test, T, N, [Ref|Refs], Errors, Ws);
-p_run_loop(Test, List, N, Refs0, Errors0, Ws0) ->
- receive
- {'DOWN',Ref,process,_,Res} ->
- {Errors,Ws} = case Res of
- ok -> {Errors0,Ws0};
- error -> {Errors0+1,Ws0};
- warning -> {Errors0,Ws0+1}
- end,
- Refs = Refs0 -- [Ref],
- p_run_loop(Test, List, N, Refs, Errors, Ws)
- end.
diff --git a/lib/compiler/test/compiler.cover b/lib/compiler/test/compiler.cover
index 5ec2408a35..69d284ea6c 100644
--- a/lib/compiler/test/compiler.cover
+++ b/lib/compiler/test/compiler.cover
@@ -1,3 +1,3 @@
%% -*- erlang -*-
-{exclude,[sys_pre_attributes,core_parse]}.
+{exclude,[sys_pre_attributes,core_scan,core_parse]}.
diff --git a/lib/compiler/test/core_SUITE_data/.gitignore b/lib/compiler/test/core_SUITE_data/.gitignore
new file mode 100644
index 0000000000..d11d93d37f
--- /dev/null
+++ b/lib/compiler/test/core_SUITE_data/.gitignore
@@ -0,0 +1 @@
+!*.core
diff --git a/lib/compiler/test/error_SUITE.erl b/lib/compiler/test/error_SUITE.erl
index 4530313bb0..0874225a62 100644
--- a/lib/compiler/test/error_SUITE.erl
+++ b/lib/compiler/test/error_SUITE.erl
@@ -21,11 +21,133 @@
-include("test_server.hrl").
-export([all/1,
- head_mismatch_line/1,warnings_as_errors/1]).
+ head_mismatch_line/1,warnings_as_errors/1, bif_clashes/1]).
all(suite) ->
test_lib:recompile(?MODULE),
- [head_mismatch_line,warnings_as_errors].
+ [head_mismatch_line,warnings_as_errors,bif_clashes].
+
+
+bif_clashes(Config) when is_list(Config) ->
+ Ts = [{bif_clashes1,
+ <<"
+ -export([t/0]).
+ t() ->
+ length([a,b,c]).
+
+ length(X) ->
+ erlang:length(X).
+ ">>,
+ [return_warnings],
+ {error,
+ [{4, erl_lint,{call_to_redefined_old_bif,{length,1}}}], []} }],
+ ?line [] = run(Config, Ts),
+ Ts1 = [{bif_clashes2,
+ <<"
+ -export([t/0]).
+ -import(x,[length/1]).
+ t() ->
+ length([a,b,c]).
+ ">>,
+ [return_warnings],
+ {error,
+ [{3, erl_lint,{redefine_old_bif_import,{length,1}}}], []} }],
+ ?line [] = run(Config, Ts1),
+ Ts00 = [{bif_clashes3,
+ <<"
+ -export([t/0]).
+ -compile({no_auto_import,[length/1]}).
+ t() ->
+ length([a,b,c]).
+
+ length(X) ->
+ erlang:length(X).
+ ">>,
+ [return_warnings],
+ []}],
+ ?line [] = run(Config, Ts00),
+ Ts11 = [{bif_clashes4,
+ <<"
+ -export([t/0]).
+ -compile({no_auto_import,[length/1]}).
+ -import(x,[length/1]).
+ t() ->
+ length([a,b,c]).
+ ">>,
+ [return_warnings],
+ []}],
+ ?line [] = run(Config, Ts11),
+ Ts000 = [{bif_clashes5,
+ <<"
+ -export([t/0]).
+ t() ->
+ binary_part(<<1,2,3,4>>,1,2).
+
+ binary_part(X,Y,Z) ->
+ erlang:binary_part(X,Y,Z).
+ ">>,
+ [return_warnings],
+ {warning,
+ [{4, erl_lint,{call_to_redefined_bif,{binary_part,3}}}]} }],
+ ?line [] = run(Config, Ts000),
+ Ts111 = [{bif_clashes6,
+ <<"
+ -export([t/0]).
+ -import(x,[binary_part/3]).
+ t() ->
+ binary_part(<<1,2,3,4>>,1,2).
+ ">>,
+ [return_warnings],
+ {warning,
+ [{3, erl_lint,{redefine_bif_import,{binary_part,3}}}]} }],
+ ?line [] = run(Config, Ts111),
+ Ts2 = [{bif_clashes7,
+ <<"
+ -export([t/0]).
+ -compile({no_auto_import,[length/1]}).
+ -import(x,[length/1]).
+ t() ->
+ length([a,b,c]).
+ length(X) ->
+ erlang:length(X).
+ ">>,
+ [],
+ {error,
+ [{7,erl_lint,{define_import,{length,1}}}],
+ []} }],
+ ?line [] = run2(Config, Ts2),
+ Ts3 = [{bif_clashes8,
+ <<"
+ -export([t/1]).
+ -compile({no_auto_import,[length/1]}).
+ t(X) when length(X) > 3 ->
+ length([a,b,c]).
+ length(X) ->
+ erlang:length(X).
+ ">>,
+ [],
+ {error,
+ [{4,erl_lint,illegal_guard_expr}],
+ []} }],
+ ?line [] = run2(Config, Ts3),
+ Ts4 = [{bif_clashes9,
+ <<"
+ -export([t/1]).
+ -compile({no_auto_import,[length/1]}).
+ -import(x,[length/1]).
+ t(X) when length(X) > 3 ->
+ length([a,b,c]).
+ ">>,
+ [],
+ {error,
+ [{5,erl_lint,illegal_guard_expr}],
+ []} }],
+ ?line [] = run2(Config, Ts4),
+
+ ok.
+
+
+
%% Tests that a head mismatch is reported on the correct line (OTP-2125).
head_mismatch_line(Config) when is_list(Config) ->
@@ -49,7 +171,7 @@ warnings_as_errors(Config) when is_list(Config) ->
A = unused,
ok.
">>,
- [warnings_as_errors],
+ [export_all,warnings_as_errors],
{error,
[],
[{3,erl_lint,{unused_var,'A'}}]} }],
@@ -70,6 +192,24 @@ run(Config, Tests) ->
end,
lists:foldl(F, [], Tests).
+run2(Config, Tests) ->
+ F = fun({N,P,Ws,E}, BadL) ->
+ case catch filter(run_test(Config, P, Ws)) of
+ E ->
+ BadL;
+ Bad ->
+ ?t:format("~nTest ~p failed. Expected~n ~p~n"
+ "but got~n ~p~n", [N, E, Bad]),
+ fail()
+ end
+ end,
+ lists:foldl(F, [], Tests).
+
+filter({error,Es,_Ws}) ->
+ {error,Es,[]};
+filter(X) ->
+ X.
+
%% Compiles a test module and returns the list of errors and warnings.
@@ -78,17 +218,29 @@ run_test(Conf, Test0, Warnings) ->
?line DataDir = ?config(priv_dir, Conf),
?line Test = ["-module(errors_test). ", Test0],
?line File = filename:join(DataDir, Filename),
- ?line Opts = [binary,export_all,return|Warnings],
+ ?line Opts = [binary,return_errors|Warnings],
?line ok = file:write_file(File, Test),
%% Compile once just to print all errors and warnings.
- ?line compile:file(File, [binary,export_all,report|Warnings]),
+ ?line compile:file(File, [binary,report|Warnings]),
%% Test result of compilation.
?line Res = case compile:file(File, Opts) of
- {error,[{_File,Es}],Ws} ->
+ {ok,errors_test,_,[{_File,Ws}]} ->
+ %io:format("compile:file(~s,~p) ->~n~p~n",
+ % [File,Opts,Ws]),
+ {warning,Ws};
+ {ok,errors_test,_,[]} ->
+ %io:format("compile:file(~s,~p) ->~n~p~n",
+ % [File,Opts,Ws]),
+ [];
+ {error,[{XFile,Es}],Ws} = _ZZ when is_list(XFile) ->
+ %io:format("compile:file(~s,~p) ->~n~p~n",
+ % [File,Opts,_ZZ]),
{error,Es,Ws};
- {error,Es,[{_File,Ws}]} ->
+ {error,Es,[{_File,Ws}]} = _ZZ->
+ %io:format("compile:file(~s,~p) ->~n~p~n",
+ % [File,Opts,_ZZ]),
{error,Es,Ws}
end,
file:delete(File),
diff --git a/lib/compiler/test/float_SUITE.erl b/lib/compiler/test/float_SUITE.erl
index 07779ddd5a..b48b1daa32 100644
--- a/lib/compiler/test/float_SUITE.erl
+++ b/lib/compiler/test/float_SUITE.erl
@@ -82,6 +82,14 @@ bad_negate(X, Y) when is_float(X) ->
Y1 = -Y, %BIF call.
{X2, Y1}.
+%% Some math functions are not implemented on all platforms.
+-define(OPTIONAL(Expected, Expr),
+ try
+ Expected = Expr
+ catch
+ error:undef -> ok
+ end).
+
math_functions(Config) when is_list(Config) ->
%% Mostly silly coverage.
?line 0.0 = math:tan(0),
@@ -93,6 +101,14 @@ math_functions(Config) when is_list(Config) ->
?line -1.0 = math:cos(math:pi()),
?line 1.0 = math:exp(0),
?line 1.0 = math:pow(math:pi(), 0),
+ ?line 0.0 = math:log(1),
+ ?line 0.0 = math:asin(0),
+ ?line 0.0 = math:acos(1),
+ ?line ?OPTIONAL(0.0, math:asinh(0)),
+ ?line ?OPTIONAL(0.0, math:acosh(1)),
+ ?line ?OPTIONAL(0.0, math:atanh(0)),
+ ?line ?OPTIONAL(0.0, math:erf(0)),
+ ?line ?OPTIONAL(1.0, math:erfc(0)),
?line 0.0 = math:tan(id(0)),
?line 0.0 = math:atan2(id(0), 1),
@@ -101,6 +117,14 @@ math_functions(Config) when is_list(Config) ->
?line 0.0 = math:tanh(id(0)),
?line 1.0 = math:log10(id(10)),
?line 1.0 = math:exp(id(0)),
+ ?line 0.0 = math:log(id(1)),
+ ?line 0.0 = math:asin(id(0)),
+ ?line 0.0 = math:acos(id(1)),
+ ?line ?OPTIONAL(0.0, math:asinh(id(0))),
+ ?line ?OPTIONAL(0.0, math:acosh(id(1))),
+ ?line ?OPTIONAL(0.0, math:atanh(id(0))),
+ ?line ?OPTIONAL(0.0, math:erf(id(0))),
+ ?line ?OPTIONAL(1.0, math:erfc(id(0))),
%% Only for coverage (of beam_type.erl).
?line {'EXIT',{undef,_}} = (catch math:fnurfla(0)),
diff --git a/lib/compiler/test/guard_SUITE.erl b/lib/compiler/test/guard_SUITE.erl
index f3960b28c3..8f23bd2e5a 100644
--- a/lib/compiler/test/guard_SUITE.erl
+++ b/lib/compiler/test/guard_SUITE.erl
@@ -31,7 +31,7 @@
t_is_boolean/1,is_function_2/1,
tricky/1,rel_ops/1,literal_type_tests/1,
basic_andalso_orelse/1,traverse_dcd/1,
- check_qlc_hrl/1,andalso_semi/1,tuple_size/1]).
+ check_qlc_hrl/1,andalso_semi/1,t_tuple_size/1,binary_part/1]).
all(suite) ->
test_lib:recompile(?MODULE),
@@ -43,7 +43,7 @@ all(suite) ->
build_in_guard,old_guard_tests,gbif,
t_is_boolean,is_function_2,tricky,rel_ops,literal_type_tests,
basic_andalso_orelse,traverse_dcd,check_qlc_hrl,andalso_semi,
- tuple_size].
+ t_tuple_size,binary_part].
misc(Config) when is_list(Config) ->
?line 42 = case id(42) of
@@ -1330,7 +1330,7 @@ andalso_semi_bar(Bar) when is_list(Bar) andalso length(Bar) =:= 3; Bar =:= 1 ->
ok.
-tuple_size(Config) when is_list(Config) ->
+t_tuple_size(Config) when is_list(Config) ->
?line 10 = do_tuple_size({1,2,3,4}),
?line fc(catch do_tuple_size({1,2,3})),
?line fc(catch do_tuple_size(42)),
@@ -1362,6 +1362,146 @@ ludicrous_tuple_size(T)
when tuple_size(T) =:= 16#FFFFFFFFFFFFFFFF -> ok;
ludicrous_tuple_size(_) -> error.
+%%
+%% The binary_part/2,3 guard BIFs
+%%
+-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))).
+mask_error({'EXIT',{Err,_}}) ->
+ Err;
+mask_error(Else) ->
+ Else.
+
+binary_part(doc) ->
+ ["Tests the binary_part/2,3 guard (GC) bif's"];
+binary_part(Config) when is_list(Config) ->
+ %% This is more or less a copy of what the guard_SUITE in emulator
+ %% does to cover the guard bif's
+ ?line 1 = bptest(<<1,2,3>>),
+ ?line 2 = bptest(<<2,1,3>>),
+ ?line error = bptest(<<1>>),
+ ?line error = bptest(<<>>),
+ ?line error = bptest(apa),
+ ?line 3 = bptest(<<2,3,3>>),
+ % With one variable (pos)
+ ?line 1 = bptest(<<1,2,3>>,1),
+ ?line 2 = bptest(<<2,1,3>>,1),
+ ?line error = bptest(<<1>>,1),
+ ?line error = bptest(<<>>,1),
+ ?line error = bptest(apa,1),
+ ?line 3 = bptest(<<2,3,3>>,1),
+ % With one variable (length)
+ ?line 1 = bptesty(<<1,2,3>>,1),
+ ?line 2 = bptesty(<<2,1,3>>,1),
+ ?line error = bptesty(<<1>>,1),
+ ?line error = bptesty(<<>>,1),
+ ?line error = bptesty(apa,1),
+ ?line 3 = bptesty(<<2,3,3>>,2),
+ % With one variable (whole tuple)
+ ?line 1 = bptestx(<<1,2,3>>,{1,1}),
+ ?line 2 = bptestx(<<2,1,3>>,{1,1}),
+ ?line error = bptestx(<<1>>,{1,1}),
+ ?line error = bptestx(<<>>,{1,1}),
+ ?line error = bptestx(apa,{1,1}),
+ ?line 3 = bptestx(<<2,3,3>>,{1,2}),
+ % With two variables
+ ?line 1 = bptest(<<1,2,3>>,1,1),
+ ?line 2 = bptest(<<2,1,3>>,1,1),
+ ?line error = bptest(<<1>>,1,1),
+ ?line error = bptest(<<>>,1,1),
+ ?line error = bptest(apa,1,1),
+ ?line 3 = bptest(<<2,3,3>>,1,2),
+ % Direct (autoimported) call, these will be evaluated by the compiler...
+ ?line <<2>> = binary_part(<<1,2,3>>,1,1),
+ ?line <<1>> = binary_part(<<2,1,3>>,1,1),
+ % Compiler warnings due to constant evaluation expected (3)
+ ?line badarg = ?MASK_ERROR(binary_part(<<1>>,1,1)),
+ ?line badarg = ?MASK_ERROR(binary_part(<<>>,1,1)),
+ ?line badarg = ?MASK_ERROR(binary_part(apa,1,1)),
+ ?line <<3,3>> = binary_part(<<2,3,3>>,1,2),
+ % Direct call through apply
+ ?line <<2>> = apply(erlang,binary_part,[<<1,2,3>>,1,1]),
+ ?line <<1>> = apply(erlang,binary_part,[<<2,1,3>>,1,1]),
+ % Compiler warnings due to constant evaluation expected (3)
+ ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<1>>,1,1])),
+ ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[<<>>,1,1])),
+ ?line badarg = ?MASK_ERROR(apply(erlang,binary_part,[apa,1,1])),
+ ?line <<3,3>> = apply(erlang,binary_part,[<<2,3,3>>,1,2]),
+ % Constant propagation
+ ?line Bin = <<1,2,3>>,
+ ?line ok = if
+ binary_part(Bin,1,1) =:= <<2>> ->
+ ok;
+ %% Compiler warning, clause cannot match (expected)
+ true ->
+ error
+ end,
+ ?line ok = if
+ binary_part(Bin,{1,1}) =:= <<2>> ->
+ ok;
+ %% Compiler warning, clause cannot match (expected)
+ true ->
+ error
+ end,
+ ok.
+
+
+bptest(B) when length(B) =:= 1337 ->
+ 1;
+bptest(B) when binary_part(B,{1,1}) =:= <<2>> ->
+ 1;
+bptest(B) when erlang:binary_part(B,1,1) =:= <<1>> ->
+ 2;
+bptest(B) when erlang:binary_part(B,{1,2}) =:= <<3,3>> ->
+ 3;
+bptest(_) ->
+ error.
+
+bptest(B,A) when length(B) =:= A ->
+ 1;
+bptest(B,A) when binary_part(B,{A,1}) =:= <<2>> ->
+ 1;
+bptest(B,A) when erlang:binary_part(B,A,1) =:= <<1>> ->
+ 2;
+bptest(B,A) when erlang:binary_part(B,{A,2}) =:= <<3,3>> ->
+ 3;
+bptest(_,_) ->
+ error.
+
+bptestx(B,A) when length(B) =:= A ->
+ 1;
+bptestx(B,A) when binary_part(B,A) =:= <<2>> ->
+ 1;
+bptestx(B,A) when erlang:binary_part(B,A) =:= <<1>> ->
+ 2;
+bptestx(B,A) when erlang:binary_part(B,A) =:= <<3,3>> ->
+ 3;
+bptestx(_,_) ->
+ error.
+
+bptesty(B,A) when length(B) =:= A ->
+ 1;
+bptesty(B,A) when binary_part(B,{1,A}) =:= <<2>> ->
+ 1;
+bptesty(B,A) when erlang:binary_part(B,1,A) =:= <<1>> ->
+ 2;
+bptesty(B,A) when erlang:binary_part(B,{1,A}) =:= <<3,3>> ->
+ 3;
+bptesty(_,_) ->
+ error.
+
+bptest(B,A,_C) when length(B) =:= A ->
+ 1;
+bptest(B,A,C) when binary_part(B,{A,C}) =:= <<2>> ->
+ 1;
+bptest(B,A,C) when erlang:binary_part(B,A,C) =:= <<1>> ->
+ 2;
+bptest(B,A,C) when erlang:binary_part(B,{A,C}) =:= <<3,3>> ->
+ 3;
+bptest(_,_,_) ->
+ error.
+
+
+
%% Call this function to turn off constant propagation.
id(I) -> I.
diff --git a/lib/compiler/test/match_SUITE.erl b/lib/compiler/test/match_SUITE.erl
index 9c4687efa1..fd51b777ac 100644
--- a/lib/compiler/test/match_SUITE.erl
+++ b/lib/compiler/test/match_SUITE.erl
@@ -112,6 +112,12 @@ aliases(Config) when is_list(Config) ->
?line {42,42,42,42} = multiple_aliases_1(42),
?line {7,7,7} = multiple_aliases_2(7),
?line {{a,b},{a,b},{a,b}} = multiple_aliases_3({a,b}),
+
+ %% Lists/literals.
+ ?line {a,b} = list_alias1([a,b]),
+ ?line {a,b} = list_alias2([a,b]),
+ ?line {a,b} = list_alias3([a,b]),
+
ok.
str_alias(V) ->
@@ -206,6 +212,15 @@ multiple_aliases_2((A=B)=(A=C)) ->
multiple_aliases_3((A={_,_}=B)={_,_}=C) ->
{A,B,C}.
+list_alias1([a,b]=[X,Y]) ->
+ {X,Y}.
+
+list_alias2([X,Y]=[a,b]) ->
+ {X,Y}.
+
+list_alias3([X,b]=[a,Y]) ->
+ {X,Y}.
+
%% OTP-7018.
match_in_call(Config) when is_list(Config) ->
diff --git a/lib/compiler/test/misc_SUITE.erl b/lib/compiler/test/misc_SUITE.erl
index e096571d50..450a4e279d 100644
--- a/lib/compiler/test/misc_SUITE.erl
+++ b/lib/compiler/test/misc_SUITE.erl
@@ -1,29 +1,46 @@
%%
%% %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(misc_SUITE).
-export([all/1,init_per_testcase/2,fin_per_testcase/2,
tobias/1,empty_string/1,md5/1,silly_coverage/1,
- confused_literals/1,integer_encoding/1]).
+ confused_literals/1,integer_encoding/1,override_bif/1]).
-include("test_server.hrl").
+%% For the override_bif testcase.
+%% NB, no other testcases in this testsuite can use these without erlang:prefix!
+-compile({no_auto_import,[abs/1]}).
+-compile({no_auto_import,[binary_part/3]}).
+-compile({no_auto_import,[binary_part/2]}).
+-import(test_lib,[binary_part/2]).
+
+%% This should do no harm (except for fun byte_size/1 which does not, by design, work with import
+-compile({no_auto_import,[byte_size/1]}).
+-import(erlang,[byte_size/1]).
+
+
+
+%% Include an opaque declaration to cover the stripping of
+%% opaque types from attributes in v3_kernel.
+-opaque misc_SUITE_test_cases() :: [atom()].
+
init_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
Dog = test_server:timetrap(?t:minutes(10)),
[{watchdog,Dog}|Config].
@@ -33,10 +50,44 @@ fin_per_testcase(Case, Config) when is_atom(Case), is_list(Config) ->
?t:timetrap_cancel(Dog),
ok.
+-spec all(any()) -> misc_SUITE_test_cases().
+
all(suite) ->
test_lib:recompile(?MODULE),
[tobias,empty_string,md5,silly_coverage,confused_literals,
- integer_encoding].
+ integer_encoding, override_bif].
+
+
+%%
+%% Functions that override new and old bif's
+%%
+abs(_N) ->
+ dummy_abs.
+
+binary_part(_,_,_) ->
+ dummy_bp.
+
+% Make sure that auto-imported BIF's are overridden correctly
+
+override_bif(suite) ->
+ [];
+override_bif(doc) ->
+ ["Test dat local functions and imports override auto-imported BIFs."];
+override_bif(Config) when is_list(Config) ->
+ ?line dummy_abs = abs(1),
+ ?line dummy_bp = binary_part(<<"hello">>,1,1),
+ ?line dummy = binary_part(<<"hello">>,{1,1}),
+ ?line 1 = erlang:abs(1),
+ ?line <<"e">> = erlang:binary_part(<<"hello">>,1,1),
+ ?line <<"e">> = erlang:binary_part(<<"hello">>,{1,1}),
+ F = fun(X) when byte_size(X) =:= 4 ->
+ four;
+ (X) ->
+ byte_size(X)
+ end,
+ ?line four = F(<<1,2,3,4>>),
+ ?line 5 = F(<<1,2,3,4,5>>),
+ ok.
%% A bug reported by Tobias Lindahl for a development version of R11B.
@@ -92,13 +143,23 @@ md5_1(Beam) ->
silly_coverage(Config) when is_list(Config) ->
%% sys_core_fold, sys_core_setel, v3_kernel
BadCoreErlang = {c_module,[],
- name,exports,attrs,
+ name,[],[],
[{{c_var,[],{foo,2}},seriously_bad_body}]},
?line expect_error(fun() -> sys_core_fold:module(BadCoreErlang, []) end),
?line expect_error(fun() -> sys_core_dsetel:module(BadCoreErlang, []) end),
?line expect_error(fun() -> v3_kernel:module(BadCoreErlang, []) end),
- %% v3_codgen
+ %% v3_life
+ BadKernel = {k_mdef,[],?MODULE,
+ [{foo,0}],
+ [],
+ [{k_fdef,
+ {k,[],[],[]},
+ f,0,[],
+ seriously_bad_body}]},
+ ?line expect_error(fun() -> v3_life:module(BadKernel, []) end),
+
+ %% v3_codegen
CodegenInput = {?MODULE,[{foo,0}],[],[{function,foo,0,[a|b],a,b}]},
?line expect_error(fun() -> v3_codegen:module(CodegenInput, []) end),
@@ -154,6 +215,17 @@ silly_coverage(Config) when is_list(Config) ->
{test,bs_get_binary2,{f,99},0,[{x,0},{atom,all},1,[]],{x,0}},
{block,[a|b]}]}],0},
?line expect_error(fun() -> beam_bsm:module(BsmInput, []) end),
+
+ %% beam_receive.
+ ReceiveInput = {?MODULE,[{foo,0}],[],
+ [{function,foo,0,2,
+ [{label,1},
+ {func_info,{atom,?MODULE},{atom,foo},0},
+ {label,2},
+ {call_ext,0,{extfunc,erlang,make_ref,0}},
+ {block,[a|b]}]}],0},
+ ?line expect_error(fun() -> beam_receive:module(ReceiveInput, []) end),
+
ok.
expect_error(Fun) ->
diff --git a/lib/compiler/test/receive_SUITE.erl b/lib/compiler/test/receive_SUITE.erl
index cb8833759a..fca3f0387b 100644
--- a/lib/compiler/test/receive_SUITE.erl
+++ b/lib/compiler/test/receive_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%
%%
%%% Purpose : Compiles various modules with tough code
@@ -21,7 +21,7 @@
-module(receive_SUITE).
-export([all/1,init_per_testcase/2,fin_per_testcase/2,
- recv/1,coverage/1,otp_7980/1]).
+ recv/1,coverage/1,otp_7980/1,ref_opt/1]).
-include("test_server.hrl").
@@ -36,7 +36,7 @@ fin_per_testcase(_Case, Config) ->
all(suite) ->
test_lib:recompile(?MODULE),
- [recv,coverage,otp_7980].
+ [recv,coverage,otp_7980,ref_opt].
-record(state, {ena = true}).
@@ -157,5 +157,52 @@ otp_7980_add_clients(Count) ->
end,
N - 1
end, Count, [1,2,3]).
-
+
+ref_opt(Config) when is_list(Config) ->
+ case ?MODULE of
+ receive_SUITE -> ref_opt_1(Config);
+ _ -> {skip,"Enough to run this case once."}
+ end.
+
+ref_opt_1(Config) ->
+ ?line DataDir = ?config(data_dir, Config),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Sources = filelib:wildcard(filename:join([DataDir,"ref_opt","*.erl"])),
+ ?line test_lib:p_run(fun(Src) ->
+ do_ref_opt(Src, PrivDir)
+ end, Sources),
+ ok.
+
+do_ref_opt(Source, PrivDir) ->
+ try
+ {ok,Mod} = c:c(Source, [{outdir,PrivDir}]),
+ ok = Mod:Mod(),
+ Base = filename:rootname(filename:basename(Source), ".erl"),
+ BeamFile = filename:join(PrivDir, Base),
+ {beam_file,Mod,_,_,_,Code} = beam_disasm:file(BeamFile),
+ case Base of
+ "no_"++_ ->
+ [] = collect_recv_opt_instrs(Code);
+ "yes_"++_ ->
+ [{recv_mark,{f,L}},{recv_set,{f,L}}] =
+ collect_recv_opt_instrs(Code)
+ end,
+ ok
+ catch Class:Error ->
+ io:format("~s: ~p ~p\n~p\n",
+ [Source,Class,Error,erlang:get_stacktrace()]),
+ error
+ end.
+
+collect_recv_opt_instrs(Code) ->
+ L = [ [I || I <- Is,
+ begin
+ case I of
+ {recv_mark,{f,_}} -> true;
+ {recv_set,{f,_}} -> true;
+ _ -> false
+ end
+ end] || {function,_,_,_,Is} <- Code],
+ lists:append(L).
+
id(I) -> I.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl
new file mode 100644
index 0000000000..bc63dac437
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_1.erl
@@ -0,0 +1,99 @@
+-module(no_1).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f1(X) ->
+ Ref = make_ref(),
+ receive
+ _ when [X] =:= Ref ->
+ ok
+ end.
+
+f2(X, Y) ->
+ _Ref = make_ref(),
+ receive
+ _ when X =:= Y ->
+ ok
+ end.
+
+f3(X) ->
+ Ref = make_ref(),
+ receive
+ _ when X =:= Ref ->
+ ok
+ end.
+
+f4(X) ->
+ Ref = make_ref(),
+ receive
+ {X,_} when not X =:= Ref ->
+ ok
+ end.
+
+f5(X) ->
+ Ref = make_ref(),
+ receive
+ {Y,_} when X =:= Y; Y =:= Ref ->
+ ok
+ end.
+
+f6(X) ->
+ Ref = make_ref(),
+ receive
+ {Y,_} when Y =:= Ref; Ref =:= X ->
+ ok
+ end.
+
+f7(X) ->
+ Ref = make_ref(),
+ receive
+ {Y,_} when Y =:= Ref; not (X =:= Ref) ->
+ ok
+ end.
+
+f8(X) ->
+ Ref = make_ref(),
+ receive
+ {Y,_} when not (X =:= Ref); Y =:= Ref ->
+ ok
+ end.
+
+f9(X) ->
+ Ref = make_ref(),
+ receive
+ {Y,_} when (not (X =:= Ref)) or (Y =:= Ref) ->
+ ok
+ end.
+
+f10(X, Y) ->
+ Ref = make_ref(),
+ receive
+ {Z,_} when not (X =:= Y andalso Z =:= Ref) ->
+ ok
+ end.
+
+f11(X, Y) ->
+ Ref = make_ref(),
+ receive
+ {Z,_} when not ((X =:= Y) and (Z =:= Ref)) ->
+ ok
+ end.
+
+f12(X, Y) ->
+ Ref = make_ref(),
+ receive
+ {Z,_} when not ((Z =:= Ref) and (X =:= Y)) ->
+ ok
+ end.
+
+f13() ->
+ Ref = make_ref(),
+ RefCopy = id(Ref),
+ receive
+ _ when hd([RefCopy]) =:= Ref ->
+ ok
+ end.
+
+id(I) -> I.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl
new file mode 100644
index 0000000000..bc8d30c2ac
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_2.erl
@@ -0,0 +1,26 @@
+-module(no_2).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f1() ->
+ Ref = make_ref(),
+ receive
+ {'DOWN',Ref} ->
+ ok;
+ {'DOWN',_} ->
+ ok
+ end.
+
+f2(Pid, Msg) ->
+ Ref = erlang:monitor(process, Pid),
+ Pid ! Msg,
+ receive
+ {ok,Ref,Reply} ->
+ {ok,Reply};
+ {error,Ref,Reply} ->
+ {error,Reply};
+ {error,A,B} ->
+ {error,A,B}
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl
new file mode 100644
index 0000000000..44cf8d7f71
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/no_3.erl
@@ -0,0 +1,14 @@
+-module(no_3).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f(X) ->
+ Ref = case X of
+ false -> ref;
+ true -> make_ref()
+ end,
+ receive
+ Ref -> ok
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl
new file mode 100644
index 0000000000..e2ebe234c1
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_1.erl
@@ -0,0 +1,12 @@
+-module(yes_1).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f() ->
+ Ref = make_ref(),
+ receive
+ {Ref,Reply} ->
+ Reply
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl
new file mode 100644
index 0000000000..6077cdcab9
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_2.erl
@@ -0,0 +1,13 @@
+-module(yes_2).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f(Pid, Msg) ->
+ Ref = make_ref(),
+ Pid ! Msg,
+ receive
+ {Ref,Reply} ->
+ Reply
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl
new file mode 100644
index 0000000000..28efc542ae
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_3.erl
@@ -0,0 +1,16 @@
+-module(yes_3).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f(Pid, Msg) ->
+ Ref = make_ref(),
+ do_send(Pid, Msg),
+ receive
+ {Ref,Reply} ->
+ Reply
+ end.
+
+do_send(Pid, Msg) ->
+ Pid ! Msg.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl
new file mode 100644
index 0000000000..d1ba4832c7
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_4.erl
@@ -0,0 +1,16 @@
+-module(yes_4).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f(Pid, Msg) ->
+ Ref = make_ref(),
+ catch do_send(Pid, Msg),
+ receive
+ {Ref,Reply} ->
+ Reply
+ end.
+
+do_send(Pid, Msg) ->
+ Pid ! Msg.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl
new file mode 100644
index 0000000000..3f02fba6a6
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_5.erl
@@ -0,0 +1,46 @@
+-module(yes_5).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+do_call(Process, Label, Request, Timeout) ->
+ Node = case Process of
+ {_S, N} when is_atom(N) ->
+ N;
+ _ when is_pid(Process) ->
+ node(Process)
+ end,
+ try erlang:monitor(process, Process) of
+ Mref ->
+ catch erlang:send(Process, {Label, {self(), Mref}, Request},
+ [noconnect]),
+ receive
+ {Mref, Reply} ->
+ erlang:demonitor(Mref, [flush]),
+ {ok, Reply};
+ {'DOWN', Mref, _, _, noconnection} ->
+ exit({nodedown, Node});
+ {'DOWN', Mref, _, _, Reason} ->
+ exit(Reason)
+ after Timeout ->
+ erlang:demonitor(Mref),
+ receive
+ {'DOWN', Mref, _, _, _} -> true
+ after 0 -> true
+ end,
+ exit(timeout)
+ end
+ catch
+ error:_ ->
+ monitor_node(Node, true),
+ receive
+ {nodedown, Node} ->
+ monitor_node(Node, false),
+ exit({nodedown, Node})
+ after 0 ->
+ Tag = make_ref(),
+ Process ! {Label, {self(), Tag}, Request},
+ ?MODULE:wait_resp(Node, Tag, Timeout)
+ end
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl
new file mode 100644
index 0000000000..c54b636aa6
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_6.erl
@@ -0,0 +1,15 @@
+-module(yes_6).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f(Pid, Msg) ->
+ Ref = erlang:monitor(process, Pid),
+ Pid ! Msg,
+ receive
+ {ok,Ref,Reply} ->
+ {ok,Reply};
+ {error,Ref,Reply} ->
+ {error,Reply}
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl
new file mode 100644
index 0000000000..849eab1746
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_7.erl
@@ -0,0 +1,12 @@
+-module(yes_7).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f(X, Y) ->
+ Ref = make_ref(),
+ receive
+ {Z,_} when X =:= Y, Ref =:= Z ->
+ ok
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl
new file mode 100644
index 0000000000..a47fe8cfbf
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_8.erl
@@ -0,0 +1,15 @@
+-module(yes_8).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+%% Cover use of floating point registers.
+
+f(Pid, X) when is_float(X) ->
+ Ref = make_ref(),
+ Pid ! {X+3},
+ receive
+ Ref ->
+ ok
+ end.
diff --git a/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl
new file mode 100644
index 0000000000..97fce5e734
--- /dev/null
+++ b/lib/compiler/test/receive_SUITE_data/ref_opt/yes_9.erl
@@ -0,0 +1,13 @@
+-module(yes_9).
+-compile(export_all).
+
+?MODULE() ->
+ ok.
+
+f(Fun) ->
+ Ref = make_ref(),
+ Fun(),
+ receive
+ {Ref,Reply} ->
+ Reply
+ end.
diff --git a/lib/compiler/test/test_lib.erl b/lib/compiler/test/test_lib.erl
index 844bbfc4b9..d8799952a9 100644
--- a/lib/compiler/test/test_lib.erl
+++ b/lib/compiler/test/test_lib.erl
@@ -19,8 +19,8 @@
-module(test_lib).
-include("test_server.hrl").
-
--export([recompile/1,opt_opts/1,get_data_dir/1,smoke_disasm/1]).
+-compile({no_auto_import,[binary_part/2]}).
+-export([recompile/1,opt_opts/1,get_data_dir/1,smoke_disasm/1,p_run/2,binary_part/2]).
recompile(Mod) when is_atom(Mod) ->
case whereis(cover_server) of
@@ -72,3 +72,39 @@ get_data_dir(Config) ->
{ok,Data2,_} = regexp:sub(Data1, "_post_opt_SUITE", "_SUITE"),
{ok,Data,_} = regexp:sub(Data2, "_inline_SUITE", "_SUITE"),
Data.
+
+%% p_run(fun(Data) -> ok|error, List) -> ok
+%% Will fail the test case if there were any errors.
+
+p_run(Test, List) ->
+ N = erlang:system_info(schedulers) + 1,
+ p_run_loop(Test, List, N, [], 0, 0).
+
+p_run_loop(_, [], _, [], Errors, Ws) ->
+ case Errors of
+ 0 ->
+ case Ws of
+ 0 -> ok;
+ 1 -> {comment,"1 warning"};
+ N -> {comment,integer_to_list(N)++" warnings"}
+ end;
+ N -> ?t:fail({N,errors})
+ end;
+p_run_loop(Test, [H|T], N, Refs, Errors, Ws) when length(Refs) < N ->
+ {_,Ref} = erlang:spawn_monitor(fun() -> exit(Test(H)) end),
+ p_run_loop(Test, T, N, [Ref|Refs], Errors, Ws);
+p_run_loop(Test, List, N, Refs0, Errors0, Ws0) ->
+ receive
+ {'DOWN',Ref,process,_,Res} ->
+ {Errors,Ws} = case Res of
+ ok -> {Errors0,Ws0};
+ error -> {Errors0+1,Ws0};
+ warning -> {Errors0,Ws0+1}
+ end,
+ Refs = Refs0 -- [Ref],
+ p_run_loop(Test, List, N, Refs, Errors, Ws)
+ end.
+
+%% This is for the misc_SUITE:override_bif testcase
+binary_part(_A,_B) ->
+ dummy.
diff --git a/lib/crypto/c_src/crypto.c b/lib/crypto/c_src/crypto.c
index a71df1d7fd..bb639054a6 100644
--- a/lib/crypto/c_src/crypto.c
+++ b/lib/crypto/c_src/crypto.c
@@ -264,15 +264,15 @@ static int is_ok_load_info(ErlNifEnv* env, ERL_NIF_TERM load_info)
}
static void* crypto_alloc(size_t size)
{
- return enif_alloc(NULL, size);
+ return enif_alloc(size);
}
static void* crypto_realloc(void* ptr, size_t size)
{
- return enif_realloc(NULL, ptr, size);
+ return enif_realloc(ptr, size);
}
static void crypto_free(void* ptr)
{
- enif_free(NULL, ptr);
+ enif_free(ptr);
}
static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
@@ -289,7 +289,7 @@ static int load(ErlNifEnv* env, void** priv_data, ERL_NIF_TERM load_info)
if (sys_info.scheduler_threads > 1) {
int i;
- lock_vec = enif_alloc(env,CRYPTO_num_locks()*sizeof(*lock_vec));
+ lock_vec = enif_alloc(CRYPTO_num_locks()*sizeof(*lock_vec));
if (lock_vec==NULL) return -1;
memset(lock_vec,0,CRYPTO_num_locks()*sizeof(*lock_vec));
@@ -371,7 +371,7 @@ static void unload(ErlNifEnv* env, void* priv_data)
enif_rwlock_destroy(lock_vec[i]);
}
}
- enif_free(env,lock_vec);
+ enif_free(lock_vec);
}
}
/*else NIF library still used by other (new) module code */
@@ -994,7 +994,7 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
RSA_free(rsa);
return enif_make_badarg(env);
}
- enif_alloc_binary(env, RSA_size(rsa), &ret_bin);
+ enif_alloc_binary(RSA_size(rsa), &ret_bin);
if (is_sha) {
SHA1(data_bin.data+4, data_bin.size-4, hmacbuf);
ERL_VALGRIND_ASSERT_MEM_DEFINED(hmacbuf, SHA_DIGEST_LENGTH);
@@ -1011,13 +1011,13 @@ static ERL_NIF_TERM rsa_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
if (i) {
ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, rsa_s_len);
if (rsa_s_len != data_bin.size) {
- enif_realloc_binary(env, &ret_bin, rsa_s_len);
+ enif_realloc_binary(&ret_bin, rsa_s_len);
ERL_VALGRIND_ASSERT_MEM_DEFINED(ret_bin.data, rsa_s_len);
}
return enif_make_binary(env,&ret_bin);
}
else {
- enif_release_binary(env, &ret_bin);
+ enif_release_binary(&ret_bin);
return atom_error;
}
}
@@ -1049,13 +1049,13 @@ static ERL_NIF_TERM dss_sign_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM ar
SHA1(data_bin.data+4, data_bin.size-4, hmacbuf);
- enif_alloc_binary(env, DSA_size(dsa), &ret_bin);
+ enif_alloc_binary(DSA_size(dsa), &ret_bin);
i = DSA_sign(NID_sha1, hmacbuf, SHA_DIGEST_LENGTH,
ret_bin.data, &dsa_s_len, dsa);
DSA_free(dsa);
if (i) {
if (dsa_s_len != ret_bin.size) {
- enif_realloc_binary(env, &ret_bin, dsa_s_len);
+ enif_realloc_binary(&ret_bin, dsa_s_len);
}
return enif_make_binary(env, &ret_bin);
}
@@ -1100,7 +1100,7 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER
return enif_make_badarg(env);
}
- enif_alloc_binary(env, RSA_size(rsa), &ret_bin);
+ enif_alloc_binary(RSA_size(rsa), &ret_bin);
if (argv[3] == atom_true) {
ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len);
@@ -1115,7 +1115,7 @@ static ERL_NIF_TERM rsa_public_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TER
ret_bin.data, rsa, padding);
if (i > 0) {
ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i);
- enif_realloc_binary(env, &ret_bin, i);
+ enif_realloc_binary(&ret_bin, i);
}
}
RSA_free(rsa);
@@ -1148,7 +1148,7 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE
return enif_make_badarg(env);
}
- enif_alloc_binary(env, RSA_size(rsa), &ret_bin);
+ enif_alloc_binary(RSA_size(rsa), &ret_bin);
if (argv[3] == atom_true) {
ERL_VALGRIND_ASSERT_MEM_DEFINED(buf+i,data_len);
@@ -1163,7 +1163,7 @@ static ERL_NIF_TERM rsa_private_crypt(ErlNifEnv* env, int argc, const ERL_NIF_TE
ret_bin.data, rsa, padding);
if (i > 0) {
ERL_VALGRIND_MAKE_MEM_DEFINED(ret_bin.data, i);
- enif_realloc_binary(env, &ret_bin, i);
+ enif_realloc_binary(&ret_bin, i);
}
}
RSA_free(rsa);
@@ -1293,11 +1293,11 @@ static ERL_NIF_TERM dh_compute_key_nif(ErlNifEnv* env, int argc, const ERL_NIF_T
ret = enif_make_badarg(env);
}
else {
- enif_alloc_binary(env, DH_size(dh_params), &ret_bin);
+ enif_alloc_binary(DH_size(dh_params), &ret_bin);
i = DH_compute_key(ret_bin.data, pubkey, dh_params);
if (i > 0) {
if (i != ret_bin.size) {
- enif_realloc_binary(env, &ret_bin, i);
+ enif_realloc_binary(&ret_bin, i);
}
ret = enif_make_binary(env, &ret_bin);
}
diff --git a/lib/debugger/src/dbg_ui_trace_win.erl b/lib/debugger/src/dbg_ui_trace_win.erl
index dbf93c7f45..c6f041a63d 100644
--- a/lib/debugger/src/dbg_ui_trace_win.erl
+++ b/lib/debugger/src/dbg_ui_trace_win.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_trace_win).
@@ -106,7 +106,7 @@ create_win(GS, Title, TraceWin, Menus) ->
gs:read('CodeArea', height) +
gs:read('RB1', height) +
gs:read('ButtonArea', height) +
- max(gs:read('EvalArea', height),
+ erlang:max(gs:read('EvalArea', height),
gs:read('BindArea', height)) +
gs:read('RB2', height) +
gs:read('TraceArea', height)}),
@@ -1032,7 +1032,7 @@ config_v() ->
gs:config('RB3', {y,Y3}),
gs:config('BindArea', {y,Y3}),
- Y4 = Y3 + max(gs:read('EvalArea', height),
+ Y4 = Y3 + erlang:max(gs:read('EvalArea', height),
gs:read('BindArea', height)),
gs:config('RB2', {y,Y4}),
@@ -1061,7 +1061,7 @@ configure(WinInfo, NewW, NewH) ->
OldH = 25+gs:read('CodeArea', height)+
gs:read('RB1', height)+
gs:read('ButtonArea', height)+
- max(gs:read('EvalArea', height), gs:read('BindArea', height))+
+ erlang:max(gs:read('EvalArea', height), gs:read('BindArea', height))+
gs:read('RB2', height)+
gs:read('TraceArea', height),
@@ -1112,7 +1112,7 @@ configure_widths(OldW, NewW, Flags) ->
{_Bu,Ev,Bi,_Tr} = Flags,
%% Difference between old and new width, considering min window width
- Diff = abs(max(OldW,330)-max(NewW,330)),
+ Diff = abs(erlang:max(OldW,330)-erlang:max(NewW,330)),
%% Check how much the frames can be resized in reality
Limits = if
@@ -1166,7 +1166,7 @@ configure_heights(OldH, NewH, Flags) ->
%% Difference between old and new height, considering min win height
MinH = min_height(Flags),
- Diff = abs(max(OldH,MinH)-max(NewH,MinH)),
+ Diff = abs(erlang:max(OldH,MinH)-erlang:max(NewH,MinH)),
%% Check how much the frames can be resized in reality
{T,Sf,Ff} = if
@@ -1392,7 +1392,7 @@ rblimits('RB1',_W,H) ->
H-112;
_ ->
Y = gs:read('RB2',y),
- max(Min,Y-140)
+ erlang:max(Min,Y-140)
end,
{Min,Max};
@@ -1403,7 +1403,7 @@ rblimits('RB2',_W,H) ->
%% Min is decided by a minimum distance to 'RB1'
Y = gs:read('RB1',y),
- Min = min(Max,Y+140),
+ Min = erlang:min(Max,Y+140),
{Min,Max};
@@ -1412,13 +1412,7 @@ rblimits('RB3',W,_H) ->
%% Neither CodeArea nor BindArea should occupy
%% less than 1/3 of the total window width and EvalFrame should
%% be at least 289 pixels wide
- {max(round(W/3),289),round(2*W/3)}.
-
-max(A, B) when A>B -> A;
-max(_A, B) -> B.
-
-min(A, B) when A<B -> A;
-min(_A, B) -> B.
+ {erlang:max(round(W/3),289),round(2*W/3)}.
%%====================================================================
diff --git a/lib/debugger/src/dbg_ui_win.erl b/lib/debugger/src/dbg_ui_win.erl
index 9840aa54da..74ff2503ab 100644
--- a/lib/debugger/src/dbg_ui_win.erl
+++ b/lib/debugger/src/dbg_ui_win.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(dbg_ui_win).
@@ -76,13 +76,10 @@ min_size(Font, Strings, MinW, MinH) ->
min_size(GS, Font, [String|Strings], MinW, MinH) ->
{W, H} = gs:read(GS, {font_wh, {Font, String}}),
- min_size(GS, Font, Strings, max(MinW, W), max(MinH, H));
+ min_size(GS, Font, Strings, erlang:max(MinW, W), erlang:max(MinH, H));
min_size(_GS, _Font, [], W, H) ->
{W, H}.
-max(X, Y) when X>Y -> X;
-max(_X, Y) -> Y.
-
%%--------------------------------------------------------------------
%% create_menus(MenuBar, [Menu])
%% MenuBar = gsobj()
diff --git a/lib/debugger/src/dbg_wx_trace_win.erl b/lib/debugger/src/dbg_wx_trace_win.erl
index 3799acdc1b..2b4a1164ad 100755
--- a/lib/debugger/src/dbg_wx_trace_win.erl
+++ b/lib/debugger/src/dbg_wx_trace_win.erl
@@ -632,7 +632,7 @@ handle_event(#wx{id=?SASH_CODE, event=#wxSash{dragRect={_X,_Y,_W,H}}}, Wi) ->
Change = CH - H,
ChangeH = fun(Item) ->
{ItemW, ItemH} = wxSizerItem:getMinSize(Item),
- wxSizerItem:setInitSize(Item, ItemW, max(ItemH+Change,-1))
+ wxSizerItem:setInitSize(Item, ItemW, erlang:max(ItemH+Change,-1))
end,
if Enable ->
{IW, IH} = wxSizer:getMinSize(InfoSzr),
@@ -694,7 +694,7 @@ handle_event(#wx{id=?SASH_TRACE, event=#wxSash{dragRect={_X,_Y,_W,H}}}, Wi) ->
true -> %% Change the Eval and Bindings area
ChangeH = fun(Item) ->
{ItemW, ItemH} = wxSizerItem:getMinSize(Item),
- wxSizerItem:setInitSize(Item, ItemW, max(ItemH+Change,-1))
+ wxSizerItem:setInitSize(Item, ItemW, erlang:max(ItemH+Change,-1))
end,
{IW, IH} = wxSizer:getMinSize(InfoSzr),
[ChangeH(Child) || Child <- wxSizer:getChildren(InfoSzr)],
@@ -1021,9 +1021,3 @@ helpwin(Type, WinInfo = #winInfo{sg=Sg =#sub{in=Sa}}) ->
search -> wxWindow:setFocus(Sa#sa.search)
end,
Wi.
-
-max(X,Y) when X > Y -> X;
-max(_,Y) -> Y.
-
-
-
diff --git a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
index ab1bbe5ade..e3dd690470 100644
--- a/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_analysis_callgraph.erl
@@ -96,6 +96,9 @@ loop(#server_state{parent = Parent, legal_warnings = LegalWarnings} = State,
end;
{AnalPid, ext_calls, NewExtCalls} ->
loop(State, Analysis, NewExtCalls);
+ {AnalPid, ext_types, ExtTypes} ->
+ send_ext_types(Parent, ExtTypes),
+ loop(State, Analysis, ExtCalls);
{AnalPid, unknown_behaviours, UnknownBehaviour} ->
send_unknown_behaviours(Parent, UnknownBehaviour),
loop(State, Analysis, ExtCalls);
@@ -123,8 +126,7 @@ analysis_start(Parent, Analysis) ->
parent = Parent,
start_from = Analysis#analysis.start_from,
use_contracts = Analysis#analysis.use_contracts,
- behaviours = {Analysis#analysis.behaviours_chk,
- []}
+ behaviours = {Analysis#analysis.behaviours_chk, []}
},
Files = ordsets:from_list(Analysis#analysis.files),
{Callgraph, NoWarn, TmpCServer0} = compile_and_store(Files, State),
@@ -132,22 +134,36 @@ analysis_start(Parent, Analysis) ->
NewCServer =
try
NewRecords = dialyzer_codeserver:get_temp_records(TmpCServer0),
- OldRecords = dialyzer_plt:get_types(State#analysis_state.plt),
+ NewExpTypes = dialyzer_codeserver:get_temp_exported_types(TmpCServer0),
+ OldRecords = dialyzer_plt:get_types(Plt),
+ OldExpTypes0 = dialyzer_plt:get_exported_types(Plt),
MergedRecords = dialyzer_utils:merge_records(NewRecords, OldRecords),
+ RemMods =
+ [case Analysis#analysis.start_from of
+ byte_code -> list_to_atom(filename:basename(F, ".beam"));
+ src_code -> list_to_atom(filename:basename(F, ".erl"))
+ end || F <- Files],
+ OldExpTypes1 = dialyzer_utils:sets_filter(RemMods, OldExpTypes0),
+ MergedExpTypes = sets:union(NewExpTypes, OldExpTypes1),
TmpCServer1 = dialyzer_codeserver:set_temp_records(MergedRecords, TmpCServer0),
- TmpCServer2 = dialyzer_utils:process_record_remote_types(TmpCServer1),
- dialyzer_contracts:process_contract_remote_types(TmpCServer2)
+ TmpCServer2 =
+ dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes,
+ TmpCServer1),
+ TmpCServer3 = dialyzer_utils:process_record_remote_types(TmpCServer2),
+ dialyzer_contracts:process_contract_remote_types(TmpCServer3)
catch
throw:{error, _ErrorMsg} = Error -> exit(Error)
end,
- NewPlt = dialyzer_plt:insert_types(Plt, dialyzer_codeserver:get_records(NewCServer)),
- State0 = State#analysis_state{plt = NewPlt},
+ NewPlt0 = dialyzer_plt:insert_types(Plt, dialyzer_codeserver:get_records(NewCServer)),
+ ExpTypes = dialyzer_codeserver:get_exported_types(NewCServer),
+ NewPlt1 = dialyzer_plt:insert_exported_types(NewPlt0, ExpTypes),
+ State0 = State#analysis_state{plt = NewPlt1},
dump_callgraph(Callgraph, State0, Analysis),
State1 = State0#analysis_state{codeserver = NewCServer},
State2 = State1#analysis_state{no_warn_unused = NoWarn},
%% Remove all old versions of the files being analyzed
AllNodes = dialyzer_callgraph:all_nodes(Callgraph),
- Plt1 = dialyzer_plt:delete_list(NewPlt, AllNodes),
+ Plt1 = dialyzer_plt:delete_list(NewPlt1, AllNodes),
Exports = dialyzer_codeserver:get_exports(NewCServer),
NewCallgraph =
case Analysis#analysis.race_detection of
@@ -155,6 +171,7 @@ analysis_start(Parent, Analysis) ->
false -> Callgraph
end,
State3 = analyze_callgraph(NewCallgraph, State2#analysis_state{plt = Plt1}),
+ rcv_and_send_ext_types(Parent),
NonExports = sets:subtract(sets:from_list(AllNodes), Exports),
NonExportsList = sets:to_list(NonExports),
Plt3 = dialyzer_plt:delete_list(State3#analysis_state.plt, NonExportsList),
@@ -371,14 +388,28 @@ compile_byte(File, Callgraph, CServer, UseContracts) ->
store_core(Mod, Core, NoWarn, Callgraph, CServer) ->
Exp = get_exports_from_core(Core),
+ OldExpTypes = dialyzer_codeserver:get_temp_exported_types(CServer),
+ NewExpTypes = get_exported_types_from_core(Core),
+ MergedExpTypes = sets:union(NewExpTypes, OldExpTypes),
CServer1 = dialyzer_codeserver:insert_exports(Exp, CServer),
- {LabeledCore, CServer2} = label_core(Core, CServer1),
- store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, CServer2, NoWarn).
+ CServer2 = dialyzer_codeserver:insert_temp_exported_types(MergedExpTypes,
+ CServer1),
+ {LabeledCore, CServer3} = label_core(Core, CServer2),
+ store_code_and_build_callgraph(Mod, LabeledCore, Callgraph, CServer3, NoWarn).
abs_get_nowarn(Abs, M) ->
[{M, F, A}
|| {attribute, _, compile, {nowarn_unused_function, {F, A}}} <- Abs].
+get_exported_types_from_core(Core) ->
+ Attrs = cerl:module_attrs(Core),
+ ExpTypes1 = [cerl:concrete(L2) || {L1, L2} <- Attrs, cerl:is_literal(L1),
+ cerl:is_literal(L2),
+ cerl:concrete(L1) =:= 'export_type'],
+ ExpTypes2 = lists:flatten(ExpTypes1),
+ M = cerl:atom_val(cerl:module_name(Core)),
+ sets:from_list([{M, F, A} || {F, A} <- ExpTypes2]).
+
get_exports_from_core(Core) ->
Tree = cerl:from_records(Core),
Exports1 = cerl:module_exports(Tree),
@@ -454,6 +485,19 @@ default_includes(Dir) ->
%% Handle Messages
%%-------------------------------------------------------------------
+rcv_and_send_ext_types(Parent) ->
+ Self = self(),
+ Self ! {Self, done},
+ ExtTypes = rcv_ext_types(Self, []),
+ Parent ! {Self, ext_types, ExtTypes}.
+
+rcv_ext_types(Self, ExtTypes) ->
+ receive
+ {Self, ext_types, ExtType} ->
+ rcv_ext_types(Self, [ExtType|ExtTypes]);
+ {Self, done} -> lists:usort(ExtTypes)
+ end.
+
send_log(Parent, Msg) ->
Parent ! {self(), log, Msg},
ok.
@@ -476,6 +520,10 @@ send_ext_calls(Parent, ExtCalls) ->
Parent ! {self(), ext_calls, ExtCalls},
ok.
+send_ext_types(Parent, ExtTypes) ->
+ Parent ! {self(), ext_types, ExtTypes},
+ ok.
+
send_unknown_behaviours(Parent, UnknownBehaviours) ->
Parent ! {self(), unknown_behaviours, UnknownBehaviours},
ok.
diff --git a/lib/dialyzer/src/dialyzer_behaviours.erl b/lib/dialyzer/src/dialyzer_behaviours.erl
index 4e8dceaa8e..3fae816cfe 100644
--- a/lib/dialyzer/src/dialyzer_behaviours.erl
+++ b/lib/dialyzer/src/dialyzer_behaviours.erl
@@ -156,9 +156,11 @@ 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
+check_all_callbacks(Module, Behaviour, [{Fun, Arity, Spec}|Rest],
+ #state{codeserver = CServer} = State, Acc) ->
+ Records = dialyzer_codeserver:get_records(CServer),
+ ExpTypes = dialyzer_codeserver:get_exported_types(CServer),
+ case parse_spec(Spec, ExpTypes, Records) of
{ok, Fun, Type} ->
RetType = erl_types:t_fun_range(Type),
ArgTypes = erl_types:t_fun_args(Type),
@@ -172,7 +174,7 @@ 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) ->
+parse_spec(String, ExpTypes, Records) ->
case erl_scan:string(String) of
{ok, Tokens, _} ->
case erl_parse:parse(Tokens) of
@@ -181,7 +183,8 @@ parse_spec(String, Records) ->
{attribute, _, 'spec', {{Fun, _}, [TypeForm|_Constraint]}} ->
MaybeRemoteType = erl_types:t_from_form(TypeForm),
try
- Type = erl_types:t_solve_remote(MaybeRemoteType, Records),
+ Type = erl_types:t_solve_remote(MaybeRemoteType, ExpTypes,
+ Records),
{ok, Fun, Type}
catch
throw:{error,Msg} -> {spec_remote_error, Msg}
diff --git a/lib/dialyzer/src/dialyzer_callgraph.erl b/lib/dialyzer/src/dialyzer_callgraph.erl
index f932f43548..d3de5aaf45 100644
--- a/lib/dialyzer/src/dialyzer_callgraph.erl
+++ b/lib/dialyzer/src/dialyzer_callgraph.erl
@@ -59,6 +59,8 @@
put_named_tables/2, put_public_tables/2, put_behaviour_api_calls/2,
get_behaviour_api_calls/1]).
+-export_type([callgraph/0]).
+
-include("dialyzer.hrl").
%%----------------------------------------------------------------------
diff --git a/lib/dialyzer/src/dialyzer_cl.erl b/lib/dialyzer/src/dialyzer_cl.erl
index d533e734db..1d02c4f0dc 100644
--- a/lib/dialyzer/src/dialyzer_cl.erl
+++ b/lib/dialyzer/src/dialyzer_cl.erl
@@ -38,6 +38,7 @@
{backend_pid :: pid(),
erlang_mode = false :: boolean(),
external_calls = [] :: [mfa()],
+ external_types = [] :: [mfa()],
legal_warnings = ordsets:new() :: [dial_warn_tag()],
mod_deps = dict:new() :: dict(),
output = standard_io :: io:device(),
@@ -538,6 +539,8 @@ cl_loop(State, LogCache) ->
return_value(State, NewPlt);
{BackendPid, ext_calls, ExtCalls} ->
cl_loop(State#cl_state{external_calls = ExtCalls}, LogCache);
+ {BackendPid, ext_types, ExtTypes} ->
+ cl_loop(State#cl_state{external_types = ExtTypes}, LogCache);
{BackendPid, mod_deps, ModDeps} ->
NewState = State#cl_state{mod_deps = ModDeps},
cl_loop(NewState, LogCache);
@@ -613,6 +616,7 @@ return_value(State = #cl_state{erlang_mode = ErlangMode,
false ->
print_warnings(State),
print_ext_calls(State),
+ print_ext_types(State),
print_unknown_behaviours(State),
maybe_close_output_file(State),
{RetValue, []};
@@ -649,10 +653,41 @@ do_print_ext_calls(Output, [{M,F,A}|T], Before) ->
do_print_ext_calls(_, [], _) ->
ok.
+print_ext_types(#cl_state{report_mode = quiet}) ->
+ ok;
+print_ext_types(#cl_state{output = Output,
+ external_calls = Calls,
+ external_types = Types,
+ stored_warnings = Warnings,
+ output_format = Format}) ->
+ case Types =:= [] of
+ true -> ok;
+ false ->
+ 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 types:\n"),
+ do_print_ext_types(Output, Types, " ");
+ raw ->
+ io:put_chars(Output, "%% Unknown types:\n"),
+ do_print_ext_types(Output, Types, "%% ")
+ end
+ end.
+
+do_print_ext_types(Output, [{M,F,A}|T], Before) ->
+ io:format(Output, "~s~p:~p/~p\n", [Before,M,F,A]),
+ do_print_ext_types(Output, T, Before);
+do_print_ext_types(_, [], _) ->
+ ok.
+
%%print_unknown_behaviours(#cl_state{report_mode = quiet}) ->
%% ok;
print_unknown_behaviours(#cl_state{output = Output,
external_calls = Calls,
+ external_types = Types,
stored_warnings = Warnings,
unknown_behaviours = DupBehaviours,
legal_warnings = LegalWarnings,
@@ -662,7 +697,7 @@ print_unknown_behaviours(#cl_state{output = Output,
false -> ok;
true ->
Behaviours = lists:usort(DupBehaviours),
- case Warnings =:= [] andalso Calls =:= [] of
+ case Warnings =:= [] andalso Calls =:= [] andalso Types =:= [] of
true -> io:nl(Output); %% Need to do a newline first
false -> ok
end,
diff --git a/lib/dialyzer/src/dialyzer_codeserver.erl b/lib/dialyzer/src/dialyzer_codeserver.erl
index 3bc5fadc21..3cf090712c 100644
--- a/lib/dialyzer/src/dialyzer_codeserver.erl
+++ b/lib/dialyzer/src/dialyzer_codeserver.erl
@@ -29,15 +29,19 @@
-export([delete/1,
finalize_contracts/2,
+ finalize_exported_types/2,
finalize_records/2,
get_contracts/1,
+ get_exported_types/1,
get_exports/1,
get_records/1,
get_next_core_label/1,
get_temp_contracts/1,
+ get_temp_exported_types/1,
get_temp_records/1,
- insert/3,
- insert_exports/2,
+ insert/3,
+ insert_exports/2,
+ insert_temp_exported_types/2,
is_exported/2,
lookup_mod_code/2,
lookup_mfa_code/2,
@@ -52,17 +56,21 @@
store_contracts/3,
store_temp_contracts/3]).
+-export_type([codeserver/0]).
+
-include("dialyzer.hrl").
%%--------------------------------------------------------------------
--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()}).
+-record(codeserver, {table_pid :: pid(),
+ exported_types = sets:new() :: set(), % set(mfa())
+ temp_exported_types = sets:new() :: set(), % set(mfa())
+ 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() :: #codeserver{}.
@@ -84,6 +92,11 @@ insert(Mod, ModCode, CS) ->
NewTablePid = table__insert(CS#codeserver.table_pid, Mod, ModCode),
CS#codeserver{table_pid = NewTablePid}.
+-spec insert_temp_exported_types(set(), codeserver()) -> codeserver().
+
+insert_temp_exported_types(Set, CS) ->
+ CS#codeserver{temp_exported_types = Set}.
+
-spec insert_exports([mfa()], codeserver()) -> codeserver().
insert_exports(List, #codeserver{exports = Exports} = CS) ->
@@ -96,11 +109,26 @@ insert_exports(List, #codeserver{exports = Exports} = CS) ->
is_exported(MFA, #codeserver{exports = Exports}) ->
sets:is_element(MFA, Exports).
+-spec get_exported_types(codeserver()) -> set(). % set(mfa())
+
+get_exported_types(#codeserver{exported_types = ExpTypes}) ->
+ ExpTypes.
+
+-spec get_temp_exported_types(codeserver()) -> set().
+
+get_temp_exported_types(#codeserver{temp_exported_types = TempExpTypes}) ->
+ TempExpTypes.
+
-spec get_exports(codeserver()) -> set(). % set(mfa())
get_exports(#codeserver{exports = Exports}) ->
Exports.
+-spec finalize_exported_types(set(), codeserver()) -> codeserver().
+
+finalize_exported_types(Set, CS) ->
+ CS#codeserver{exported_types = Set, temp_exported_types = sets:new()}.
+
-spec lookup_mod_code(module(), codeserver()) -> cerl:c_module().
lookup_mod_code(Mod, CS) when is_atom(Mod) ->
diff --git a/lib/dialyzer/src/dialyzer_contracts.erl b/lib/dialyzer/src/dialyzer_contracts.erl
index 3486c72748..2bedf99e42 100644
--- a/lib/dialyzer/src/dialyzer_contracts.erl
+++ b/lib/dialyzer/src/dialyzer_contracts.erl
@@ -33,6 +33,8 @@
process_contract_remote_types/1,
store_tmp_contract/5]).
+-export_type([file_contract/0, plt_contracts/0]).
+
%%-----------------------------------------------------------------------
-include("dialyzer.hrl").
@@ -50,7 +52,7 @@
%% to expand records and/or remote types that they might contain.
%%-----------------------------------------------------------------------
--type tmp_contract_fun() :: fun((dict()) -> contract_pair()).
+-type tmp_contract_fun() :: fun((set(), dict()) -> contract_pair()).
-record(tmp_contract, {contract_funs = [] :: [tmp_contract_fun()],
forms = [] :: [{_, _}]}).
@@ -140,10 +142,11 @@ sequence([H|T], Delimiter) -> H ++ Delimiter ++ sequence(T, Delimiter).
process_contract_remote_types(CodeServer) ->
TmpContractDict = dialyzer_codeserver:get_temp_contracts(CodeServer),
+ ExpTypes = dialyzer_codeserver:get_exported_types(CodeServer),
RecordDict = dialyzer_codeserver:get_records(CodeServer),
ContractFun =
fun({_M, _F, _A}, {File, #tmp_contract{contract_funs = CFuns, forms = Forms}}) ->
- NewCs = [CFun(RecordDict) || CFun <- CFuns],
+ NewCs = [CFun(ExpTypes, RecordDict) || CFun <- CFuns],
Args = general_domain(NewCs),
{File, #contract{contracts = NewCs, args = Args, forms = Forms}}
end,
@@ -354,9 +357,9 @@ contract_from_form(Forms, RecDict) ->
contract_from_form([{type, _, 'fun', [_, _]} = Form | Left], RecDict,
TypeAcc, FormAcc) ->
TypeFun =
- fun(AllRecords) ->
+ fun(ExpTypes, AllRecords) ->
Type = erl_types:t_from_form(Form, RecDict),
- NewType = erl_types:t_solve_remote(Type, AllRecords),
+ NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords),
{NewType, []}
end,
NewTypeAcc = [TypeFun | TypeAcc],
@@ -366,11 +369,12 @@ contract_from_form([{type, _L1, bounded_fun,
[{type, _L2, 'fun', [_, _]} = Form, Constr]}| Left],
RecDict, TypeAcc, FormAcc) ->
TypeFun =
- fun(AllRecords) ->
- Constr1 = [constraint_from_form(C, RecDict, AllRecords) || C <- Constr],
+ fun(ExpTypes, AllRecords) ->
+ Constr1 = [constraint_from_form(C, RecDict, ExpTypes, AllRecords)
+ || C <- Constr],
VarDict = insert_constraints(Constr1, dict:new()),
Type = erl_types:t_from_form(Form, RecDict, VarDict),
- NewType = erl_types:t_solve_remote(Type, AllRecords),
+ NewType = erl_types:t_solve_remote(Type, ExpTypes, AllRecords),
{NewType, Constr1}
end,
NewTypeAcc = [TypeFun | TypeAcc],
@@ -380,13 +384,15 @@ contract_from_form([], _RecDict, TypeAcc, FormAcc) ->
{lists:reverse(TypeAcc), lists:reverse(FormAcc)}.
constraint_from_form({type, _, constraint, [{atom, _, is_subtype},
- [Type1, Type2]]}, RecDict, AllRecords) ->
+ [Type1, Type2]]}, RecDict,
+ ExpTypes, AllRecords) ->
T1 = erl_types:t_from_form(Type1, RecDict),
T2 = erl_types:t_from_form(Type2, RecDict),
- T3 = erl_types:t_solve_remote(T1, AllRecords),
- T4 = erl_types:t_solve_remote(T2, AllRecords),
+ T3 = erl_types:t_solve_remote(T1, ExpTypes, AllRecords),
+ T4 = erl_types:t_solve_remote(T2, ExpTypes, AllRecords),
{subtype, T3, T4};
-constraint_from_form({type, _, constraint, [{atom,_,Name}, List]}, _RecDict, _) ->
+constraint_from_form({type, _, constraint, [{atom,_,Name}, List]}, _RecDict,
+ _ExpTypes, _AllRecords) ->
N = length(List),
throw({error, io_lib:format("Unsupported type guard ~w/~w\n", [Name, N])}).
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl
index 1ccfaaa52f..a3c7114ee1 100644
--- a/lib/dialyzer/src/dialyzer_dataflow.erl
+++ b/lib/dialyzer/src/dialyzer_dataflow.erl
@@ -38,6 +38,8 @@
%% Debug and test interfaces.
-export([get_top_level_signatures/2, pp/1]).
+-export_type([state/0]).
+
-include("dialyzer.hrl").
-import(erl_types,
diff --git a/lib/dialyzer/src/dialyzer_plt.erl b/lib/dialyzer/src/dialyzer_plt.erl
index e387077a46..c10375eea2 100644
--- a/lib/dialyzer/src/dialyzer_plt.erl
+++ b/lib/dialyzer/src/dialyzer_plt.erl
@@ -39,10 +39,12 @@
from_file/1,
get_default_plt/0,
get_types/1,
+ get_exported_types/1,
%% insert/3,
insert_list/2,
insert_contract_list/2,
insert_types/2,
+ insert_exported_types/2,
lookup/2,
lookup_contract/2,
lookup_module/2,
@@ -57,6 +59,8 @@
%% Debug utilities
-export([pp_non_returning/0, pp_mod/1]).
+-export_type([plt/0, plt_info/0]).
+
%%----------------------------------------------------------------------
-type mod_deps() :: dict().
@@ -70,9 +74,10 @@
%%----------------------------------------------------------------------
--record(plt, {info = table_new() :: dict(),
- types = table_new() :: dict(),
- contracts = table_new() :: dict()}).
+-record(plt, {info = table_new() :: dict(),
+ types = table_new() :: dict(),
+ contracts = table_new() :: dict(),
+ exported_types = sets:new() :: set()}).
-opaque plt() :: #plt{}.
-include("dialyzer.hrl").
@@ -80,13 +85,14 @@
-type file_md5() :: {file:filename(), binary()}.
-type plt_info() :: {[file_md5()], dict()}.
--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()]}).
+-record(file_plt, {version = "" :: string(),
+ file_md5_list = [] :: [file_md5()],
+ info = dict:new() :: dict(),
+ contracts = dict:new() :: dict(),
+ types = dict:new() :: dict(),
+ exported_types = sets:new() :: set(),
+ mod_deps :: mod_deps(),
+ implementation_md5 = [] :: [file_md5()]}).
%%----------------------------------------------------------------------
@@ -97,17 +103,21 @@ new() ->
-spec delete_module(plt(), module()) -> plt().
-delete_module(#plt{info = Info, types = Types, contracts = Contracts}, Mod) ->
+delete_module(#plt{info = Info, types = Types, contracts = Contracts,
+ exported_types = ExpTypes}, Mod) ->
#plt{info = table_delete_module(Info, Mod),
types = table_delete_module2(Types, Mod),
- contracts = table_delete_module(Contracts, Mod)}.
+ contracts = table_delete_module(Contracts, Mod),
+ exported_types = table_delete_module1(ExpTypes, Mod)}.
-spec delete_list(plt(), [mfa() | integer()]) -> plt().
-delete_list(#plt{info = Info, types = Types, contracts = Contracts}, List) ->
+delete_list(#plt{info = Info, types = Types, contracts = Contracts,
+ exported_types = ExpTypes}, List) ->
#plt{info = table_delete_list(Info, List),
types = Types,
- contracts = table_delete_list(Contracts, List)}.
+ contracts = table_delete_list(Contracts, List),
+ exported_types = ExpTypes}.
-spec insert_contract_list(plt(), dialyzer_contracts:plt_contracts()) -> plt().
@@ -150,11 +160,21 @@ lookup(#plt{info = Info}, Label) when is_integer(Label) ->
insert_types(PLT, Rec) ->
PLT#plt{types = Rec}.
+-spec insert_exported_types(plt(), set()) -> plt().
+
+insert_exported_types(PLT, Set) ->
+ PLT#plt{exported_types = Set}.
+
-spec get_types(plt()) -> dict().
get_types(#plt{types = Types}) ->
Types.
+-spec get_exported_types(plt()) -> set().
+
+get_exported_types(#plt{exported_types = ExpTypes}) ->
+ ExpTypes.
+
-type mfa_types() :: {mfa(), erl_types:erl_type(), [erl_types:erl_type()]}.
-spec lookup_module(plt(), module()) -> 'none' | {'value', [mfa_types()]}.
@@ -207,7 +227,8 @@ from_file(FileName, ReturnInfo) ->
ok ->
Plt = #plt{info = Rec#file_plt.info,
types = Rec#file_plt.types,
- contracts = Rec#file_plt.contracts},
+ contracts = Rec#file_plt.contracts,
+ exported_types = Rec#file_plt.exported_types},
case ReturnInfo of
false -> Plt;
true ->
@@ -261,15 +282,18 @@ get_record_from_file(FileName) ->
merge_plts(List) ->
InfoList = [Info || #plt{info = Info} <- List],
TypesList = [Types || #plt{types = Types} <- List],
+ ExpTypesList = [ExpTypes || #plt{exported_types = ExpTypes} <- List],
ContractsList = [Contracts || #plt{contracts = Contracts} <- List],
#plt{info = table_merge(InfoList),
types = table_merge(TypesList),
+ exported_types = sets_merge(ExpTypesList),
contracts = table_merge(ContractsList)}.
-spec to_file(file:filename(), plt(), mod_deps(), {[file_md5()], mod_deps()}) -> 'ok'.
to_file(FileName,
- #plt{info = Info, types = Types, contracts = Contracts},
+ #plt{info = Info, types = Types, contracts = Contracts,
+ exported_types = ExpTypes},
ModDeps, {MD5, OldModDeps}) ->
NewModDeps = dict:merge(fun(_Key, OldVal, NewVal) ->
ordsets:union(OldVal, NewVal)
@@ -281,6 +305,7 @@ to_file(FileName,
info = Info,
contracts = Contracts,
types = Types,
+ exported_types = ExpTypes,
mod_deps = NewModDeps,
implementation_md5 = ImplMd5},
Bin = term_to_binary(Record, [compressed]),
@@ -475,6 +500,9 @@ table_delete_module(Plt, Mod) ->
(_, _) -> true
end, Plt).
+table_delete_module1(Plt, Mod) ->
+ sets:filter(fun({M, _F, _A}) -> M =/= Mod end, Plt).
+
table_delete_module2(Plt, Mod) ->
dict:filter(fun(M, _Val) -> M =/= Mod end, Plt).
@@ -526,6 +554,15 @@ table_merge([Plt|Plts], Acc) ->
NewAcc = dict:merge(fun(_Key, Val, Val) -> Val end, Plt, Acc),
table_merge(Plts, NewAcc).
+sets_merge([H|T]) ->
+ sets_merge(T, H).
+
+sets_merge([], Acc) ->
+ Acc;
+sets_merge([Plt|Plts], Acc) ->
+ NewAcc = sets:union(Plt, Acc),
+ sets_merge(Plts, NewAcc).
+
%%---------------------------------------------------------------------------
%% Debug utilities.
diff --git a/lib/dialyzer/src/dialyzer_races.erl b/lib/dialyzer/src/dialyzer_races.erl
index 4972967960..fb16e6a75f 100644
--- a/lib/dialyzer/src/dialyzer_races.erl
+++ b/lib/dialyzer/src/dialyzer_races.erl
@@ -39,6 +39,8 @@
let_tag_new/2, new/0, put_curr_fun/3, put_fun_args/2,
put_race_analysis/2, put_race_list/3]).
+-export_type([races/0]).
+
-include("dialyzer.hrl").
%%% ===========================================================================
@@ -1704,7 +1706,6 @@ compare_types(VarArgs, WarnVarArgs, RaceWarnTag, RaceVarMap) ->
false ->
compare_var_list(VA1, WVA1, RaceVarMap) orelse
compare_argtypes(VA2, WVA2)
-
end
end;
?WARN_ETS_LOOKUP_INSERT ->
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl
index 6ea243c26f..f5bfc6ad2f 100644
--- a/lib/dialyzer/src/dialyzer_utils.erl
+++ b/lib/dialyzer/src/dialyzer_utils.erl
@@ -42,6 +42,7 @@
merge_records/2,
pp_hook/0,
process_record_remote_types/1,
+ sets_filter/2,
src_compiler_opts/0
]).
@@ -78,7 +79,7 @@ print_types1([{record, _Name} = Key|T], RecDict) ->
%%
-type abstract_code() :: [tuple()]. %% XXX: refine
--type comp_options() :: [atom()]. %% XXX: only a resticted set of options used
+-type comp_options() :: [atom()]. %% XXX: a restricted set of options is used
%% ============================================================================
%%
@@ -169,7 +170,7 @@ 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()) ->
+-spec get_record_and_type_info(abstract_code(), module(), dict()) ->
{'ok', dict()} | {'error', string()}.
get_record_and_type_info(AbstractCode, Module, RecDict) ->
@@ -278,13 +279,16 @@ type_record_fields([RecKey|Recs], RecDict) ->
process_record_remote_types(CServer) ->
TempRecords = dialyzer_codeserver:get_temp_records(CServer),
+ TempExpTypes = dialyzer_codeserver:get_temp_exported_types(CServer),
RecordFun =
fun(Key, Value) ->
case Key of
{record, _Name} ->
FieldFun =
fun(_Arity, Fields) ->
- [{Name, erl_types:t_solve_remote(Field, TempRecords)} || {Name, Field} <- Fields]
+ [{Name, erl_types:t_solve_remote(Field, TempExpTypes,
+ TempRecords)}
+ || {Name, Field} <- Fields]
end,
orddict:map(FieldFun, Value);
_Other -> Value
@@ -295,7 +299,8 @@ process_record_remote_types(CServer) ->
dict:map(RecordFun, Record)
end,
NewRecords = dict:map(ModuleFun, TempRecords),
- dialyzer_codeserver:finalize_records(NewRecords, CServer).
+ CServer1 = dialyzer_codeserver:finalize_records(NewRecords, CServer),
+ dialyzer_codeserver:finalize_exported_types(TempExpTypes, CServer1).
-spec merge_records(dict(), dict()) -> dict().
@@ -353,6 +358,20 @@ get_spec_info([], SpecDict, _RecordsDict, _ModName, _File) ->
%% ============================================================================
%%
+%% Exported types
+%%
+%% ============================================================================
+
+-spec sets_filter([module()], set()) -> set().
+
+sets_filter([], ExpTypes) ->
+ ExpTypes;
+sets_filter([Mod|Mods], ExpTypes) ->
+ NewExpTypes = sets:filter(fun({M, _F, _A}) -> M =/= Mod end, ExpTypes),
+ sets_filter(Mods, NewExpTypes).
+
+%% ============================================================================
+%%
%% Util utils
%%
%% ============================================================================
diff --git a/lib/gs/src/tool_utils.erl b/lib/gs/src/tool_utils.erl
index 697dd07151..b07e92c4f0 100644
--- a/lib/gs/src/tool_utils.erl
+++ b/lib/gs/src/tool_utils.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%
%%
@@ -224,11 +224,11 @@ help_win(Type, Parent, Strings) ->
{Wbtn0,Hbtn0} = gs:read(Lbl, {font_wh,{Font,"Cancel"}}),
%% Compute size of the objects and adjust the graphics accordingly
- Wbtn = max(Wbtn0+10, ?Wbtn),
- Hbtn = max(Hbtn0+10, ?Hbtn),
- Hent = max(Hent0+10, ?Hent),
- Wlbl = max(Wlbl0, max(Nbtn*Wbtn+(Nbtn-1)*?PAD, ?Wlbl)),
- Hlbl = max(Hlbl0, ?Hlbl),
+ Wbtn = erlang:max(Wbtn0+10, ?Wbtn),
+ Hbtn = erlang:max(Hbtn0+10, ?Hbtn),
+ Hent = erlang:max(Hent0+10, ?Hent),
+ Wlbl = erlang:max(Wlbl0, erlang:max(Nbtn*Wbtn+(Nbtn-1)*?PAD, ?Wlbl)),
+ Hlbl = erlang:max(Hlbl0, ?Hlbl),
Wwin = ?PAD+Wlbl+?PAD,
@@ -297,9 +297,6 @@ data("Yes") -> {helpwin,yes};
data("No") -> {helpwin,no};
data("Cancel") -> {helpwin,cancel}.
-max(X, Y) when X>Y -> X;
-max(_X, Y) -> Y.
-
get_coords(Parent, W, H) ->
case gs:read(Parent, x) of
X when is_integer(X) ->
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl
index f3b91b3953..758914ff9e 100644
--- a/lib/hipe/cerl/erl_types.erl
+++ b/lib/hipe/cerl/erl_types.erl
@@ -178,7 +178,7 @@
t_remote/3,
t_string/0,
t_struct_from_opaque/2,
- t_solve_remote/2,
+ t_solve_remote/3,
t_subst/2,
t_subtract/2,
t_subtract_list/2,
@@ -210,6 +210,7 @@
]).
%%-define(DO_ERL_TYPES_TEST, true).
+-compile({no_auto_import,[min/2,max/2]}).
-ifdef(DO_ERL_TYPES_TEST).
-export([test/0]).
@@ -221,6 +222,8 @@
-export([t_is_identifier/1]).
-endif.
+-export_type([erl_type/0]).
+
%%=============================================================================
%%
%% Definition of the type structure
@@ -398,7 +401,8 @@ t_is_none(_) -> false.
-spec t_opaque(module(), atom(), [_], erl_type()) -> erl_type().
t_opaque(Mod, Name, Args, Struct) ->
- ?opaque(set_singleton(#opaque{mod=Mod, name=Name, args=Args, struct=Struct})).
+ O = #opaque{mod = Mod, name = Name, args = Args, struct = Struct},
+ ?opaque(set_singleton(O)).
-spec t_is_opaque(erl_type()) -> boolean().
@@ -427,7 +431,7 @@ t_opaque_structure(?opaque(Elements)) ->
t_opaque_module(?opaque(Elements)) ->
case ordsets:size(Elements) of
1 ->
- [#opaque{mod=Module}] = ordsets:to_list(Elements),
+ [#opaque{mod = Module}] = ordsets:to_list(Elements),
Module;
_ -> throw({error, "Unexpected multiple opaque types"})
end.
@@ -631,7 +635,7 @@ 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.
+ %% XXX: Unions might be a problem, must investigate.
case t_inf(GenType, Unopaqued) of
?none -> Type;
_ -> Unopaqued
@@ -643,10 +647,10 @@ t_unopaque_on_mismatch(GenType, Type, Opaques) ->
module_builtin_opaques(Module) ->
[O || O <- all_opaque_builtins(), t_opaque_module(O) =:= Module].
-
+
%%-----------------------------------------------------------------------------
-%% Remote types
-%% These types are used for preprocessing they should never reach the analysis stage
+%% Remote types: these types are used for preprocessing;
+%% they should never reach the analysis stage.
-spec t_remote(module(), atom(), [_]) -> erl_type().
@@ -658,126 +662,133 @@ t_remote(Mod, Name, Args) ->
t_is_remote(?remote(_)) -> true;
t_is_remote(_) -> false.
--spec t_solve_remote(erl_type(), dict()) -> erl_type().
+-spec t_solve_remote(erl_type(), set(), dict()) -> erl_type().
-t_solve_remote(Type , Records) ->
- {RT, _RR} = t_solve_remote(Type, Records, []),
+t_solve_remote(Type, ExpTypes, Records) ->
+ {RT, _RR} = t_solve_remote(Type, ExpTypes, Records, []),
RT.
-t_solve_remote(?function(Domain, Range), R, C) ->
- {RT1, RR1} = t_solve_remote(Domain, R, C),
- {RT2, RR2} = t_solve_remote(Range, R, C),
+t_solve_remote(?function(Domain, Range), ET, R, C) ->
+ {RT1, RR1} = t_solve_remote(Domain, ET, R, C),
+ {RT2, RR2} = t_solve_remote(Range, ET, R, C),
{?function(RT1, RT2), RR1 ++ RR2};
-t_solve_remote(?list(Types, Term, Size), R, C) ->
- {RT, RR} = t_solve_remote(Types, R, C),
+t_solve_remote(?list(Types, Term, Size), ET, R, C) ->
+ {RT, RR} = t_solve_remote(Types, ET, R, C),
{?list(RT, Term, Size), RR};
-t_solve_remote(?product(Types), R, C) ->
- {RL, RR} = list_solve_remote(Types, R, C),
+t_solve_remote(?product(Types), ET, R, C) ->
+ {RL, RR} = list_solve_remote(Types, ET, R, C),
{?product(RL), RR};
-t_solve_remote(?opaque(Set), R, C) ->
+t_solve_remote(?opaque(Set), ET, R, C) ->
List = ordsets:to_list(Set),
- {NewList, RR} = opaques_solve_remote(List, R, C),
+ {NewList, RR} = opaques_solve_remote(List, ET, 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) ->
- {RL, RR} = list_solve_remote(Types, R, C),
+t_solve_remote(?tuple(?any, _, _) = T, _ET, _R, _C) -> {T, []};
+t_solve_remote(?tuple(Types, Arity, Tag), ET, R, C) ->
+ {RL, RR} = list_solve_remote(Types, ET, R, C),
{?tuple(RL, Arity, Tag), RR};
-t_solve_remote(?tuple_set(Set), R, C) ->
- {NewSet, RR} = tuples_solve_remote(Set, R, C),
+t_solve_remote(?tuple_set(Set), ET, R, C) ->
+ {NewSet, RR} = tuples_solve_remote(Set, ET, R, C),
{?tuple_set(NewSet), RR};
-t_solve_remote(?remote(Set), R, C) ->
+t_solve_remote(?remote(Set), ET, R, C) ->
RemoteList = ordsets:to_list(Set),
- {RL, RR} = list_solve_remote_type(RemoteList, R, C),
+ {RL, RR} = list_solve_remote_type(RemoteList, ET, R, C),
{t_sup(RL), RR};
-t_solve_remote(?union(List), R, C) ->
- {RL, RR} = list_solve_remote(List, R, C),
+t_solve_remote(?union(List), ET, R, C) ->
+ {RL, RR} = list_solve_remote(List, ET, R, C),
{t_sup(RL), RR};
-t_solve_remote(T, _R, _C) -> {T, []}.
+t_solve_remote(T, _ET, _R, _C) -> {T, []}.
t_solve_remote_type(#remote{mod = RemMod, name = Name, args = Args} = RemType,
- R, C) ->
+ ET, R, C) ->
+ ArgsLen = length(Args),
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});
+ self() ! {self(), ext_types, {RemMod, Name, ArgsLen}},
+ {t_any(), []};
{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]),
+ MFA = {RemMod, Name, ArgsLen},
+ case sets:is_element(MFA, ET) of
+ true ->
+ case lookup_type(Name, RemDict) of
+ {type, {_Mod, Type, ArgNames}} when ArgsLen =:= 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, ET, 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 ArgsLen =:= 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, ET, 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;
+ false ->
+ Msg = io_lib:format("Unable to find exported type ~w:~w/~w\n",
+ [RemMod, Name, ArgsLen]),
throw({error, Msg})
end
end.
-list_solve_remote([], _R, _C) ->
+list_solve_remote([], _ET, _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),
+list_solve_remote([Type|Types], ET, R, C) ->
+ {RT, RR1} = t_solve_remote(Type, ET, R, C),
+ {RL, RR2} = list_solve_remote(Types, ET, R, C),
{[RT|RL], RR1 ++ RR2}.
-list_solve_remote_type([], _R, _C) ->
+list_solve_remote_type([], _ET, _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),
+list_solve_remote_type([Type|Types], ET, R, C) ->
+ {RT, RR1} = t_solve_remote_type(Type, ET, R, C),
+ {RL, RR2} = list_solve_remote_type(Types, ET, R, C),
{[RT|RL], RR1 ++ RR2}.
-opaques_solve_remote([], _R, _C) ->
+opaques_solve_remote([], _ET, _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),
+opaques_solve_remote([#opaque{struct = Struct} = Remote|Tail], ET, R, C) ->
+ {RT, RR1} = t_solve_remote(Struct, ET, R, C),
+ {LOp, RR2} = opaques_solve_remote(Tail, ET, R, C),
{[Remote#opaque{struct = RT}|LOp], RR1 ++ RR2}.
-tuples_solve_remote([], _R, _C) ->
+tuples_solve_remote([], _ET, _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),
+tuples_solve_remote([{Sz, Tuples}|Tail], ET, R, C) ->
+ {RL, RR1} = list_solve_remote(Tuples, ET, R, C),
+ {LSzTpls, RR2} = tuples_solve_remote(Tail, ET, R, C),
{[{Sz, RL}|LSzTpls], RR1 ++ RR2}.
%%-----------------------------------------------------------------------------
@@ -801,7 +812,7 @@ t_is_none_or_unit(?unit) -> true;
t_is_none_or_unit(_) -> false.
%%-----------------------------------------------------------------------------
-%% Atoms and the derived type bool
+%% Atoms and the derived type boolean
%%
-spec t_atom() -> erl_type().
@@ -2523,12 +2534,14 @@ t_subst(T, _Dict, _Fun) ->
%% Unification
%%
--spec t_unify(erl_type(), erl_type()) -> {erl_type(), [{_, erl_type()}]}.
+-type t_unify_ret() :: {erl_type(), [{_, erl_type()}]}.
+
+-spec t_unify(erl_type(), erl_type()) -> t_unify_ret().
t_unify(T1, T2) ->
t_unify(T1, T2, []).
--spec t_unify(erl_type(), erl_type(), [erl_type()]) -> {erl_type(), [{_, erl_type()}]}.
+-spec t_unify(erl_type(), erl_type(), [erl_type()]) -> t_unify_ret().
t_unify(T1, T2, Opaques) ->
{T, Dict} = t_unify(T1, T2, dict:new(), Opaques),
@@ -2541,7 +2554,7 @@ t_unify(?var(Id1) = T, ?var(Id2), Dict, Opaques) ->
error ->
case dict:find(Id2, Dict) of
error -> {T, dict:store(Id2, T, Dict)};
- {ok, Type} -> {Type, t_unify(T, Type, Dict, Opaques)}
+ {ok, Type} -> t_unify(T, Type, Dict, Opaques)
end;
{ok, Type1} ->
case dict:find(Id2, Dict) of
@@ -3338,8 +3351,8 @@ sequence([], [], _Delimiter) ->
[];
sequence([T], Acc, _Delimiter) ->
lists:flatten(lists:reverse([T|Acc]));
-sequence([T|Left], Acc, Delimiter) ->
- sequence(Left, [T ++ Delimiter|Acc], Delimiter).
+sequence([T|Ts], Acc, Delimiter) ->
+ sequence(Ts, [T ++ Delimiter|Acc], Delimiter).
%%=============================================================================
%%
diff --git a/lib/hipe/flow/hipe_dominators.erl b/lib/hipe/flow/hipe_dominators.erl
index 3bfa6d43c4..17357461a5 100644
--- a/lib/hipe/flow/hipe_dominators.erl
+++ b/lib/hipe/flow/hipe_dominators.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %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,8 @@
domFrontier_create/2,
domFrontier_get/2]).
+-export_type([domTree/0]).
+
-include("cfg.hrl").
%%========================================================================
diff --git a/lib/hipe/icode/hipe_beam_to_icode.erl b/lib/hipe/icode/hipe_beam_to_icode.erl
index 3923e98673..1f8be4040e 100644
--- a/lib/hipe/icode/hipe_beam_to_icode.erl
+++ b/lib/hipe/icode/hipe_beam_to_icode.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %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%
%%
%%=======================================================================
@@ -22,8 +22,6 @@
%% Author : Kostis Sagonas
%% Description : Translates symbolic BEAM code to Icode
%%=======================================================================
-%% $Id$
-%%=======================================================================
%% @doc
%% This file translates symbolic BEAM code to Icode which is HiPE's
%% intermediate code representation. Either the code of an entire
@@ -431,6 +429,11 @@ trans_fun([{wait_timeout,{_,Lbl},Reg}|Instructions], Env) ->
SuspTmout = hipe_icode:mk_if(suspend_msg_timeout,[],
map_label(Lbl),hipe_icode:label_name(DoneLbl)),
Movs ++ [SetTmout, SuspTmout, DoneLbl | trans_fun(Instructions,Env1)];
+%%--- recv_mark/1 & recv_set/1 --- XXX: Handle better??
+trans_fun([{recv_mark,{f,_}}|Instructions], Env) ->
+ trans_fun(Instructions,Env);
+trans_fun([{recv_set,{f,_}}|Instructions], Env) ->
+ trans_fun(Instructions,Env);
%%--------------------------------------------------------------------
%%--- Translation of arithmetics {bif,ArithOp, ...} ---
%%--------------------------------------------------------------------
@@ -892,11 +895,6 @@ trans_fun([{bs_init_bits,{f,Lbl},Size,_Words,_LiveRegs,{field_flags,Flags0},X}|
end,
trans_bin_call({hipe_bs_primop,Name}, Lbl, Args, [Dst, Base, Offset],
Base, Offset, Env, Instructions);
-trans_fun([{bs_bits_to_bytes2, Bits, Bytes}|Instructions], Env) ->
- Src = trans_arg(Bits),
- Dst = mk_var(Bytes),
- [hipe_icode:mk_primop([Dst], 'bsl', [Src, hipe_icode:mk_const(3)])|
- trans_fun(Instructions,Env)];
trans_fun([{bs_add, {f,Lbl}, [Old,New,Unit], Res}|Instructions], Env) ->
Dst = mk_var(Res),
Temp = mk_var(new),
@@ -1126,13 +1124,6 @@ trans_fun([{gc_bif,Name,Fail,_Live,SrcRs,DstR}|Instructions], Env) ->
trans_fun([{bif,Name,Fail,SrcRs,DstR}|Instructions], Env)
end;
%%--------------------------------------------------------------------
-%% Instruction for constant pool added in February 2007 for R11B-4.
-%%--------------------------------------------------------------------
-trans_fun([{put_literal,{literal,Literal},DstR}|Instructions], Env) ->
- DstV = mk_var(DstR),
- Move = hipe_icode:mk_move(DstV, hipe_icode:mk_const(Literal)),
- [Move | trans_fun(Instructions, Env)];
-%%--------------------------------------------------------------------
%% New test instruction added in July 2007 for R12.
%%--------------------------------------------------------------------
%%--- is_bitstr ---
diff --git a/lib/hipe/icode/hipe_icode.erl b/lib/hipe/icode/hipe_icode.erl
index a4614d7237..3e211bf385 100644
--- a/lib/hipe/icode/hipe_icode.erl
+++ b/lib/hipe/icode/hipe_icode.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %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%
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1578,27 +1578,19 @@ redirect_jmp(Jmp, ToOld, ToNew) ->
_ -> Jmp
end
end,
- simplify_branch(NewI).
-
-%%
-%% @doc Turns a branch into a goto if it has only one successor and it
-%% is safe to do so.
-%%
-
--spec simplify_branch(icode_instr()) -> icode_instr().
-
-simplify_branch(I) ->
- case ordsets:from_list(successors(I)) of
+ %% Turn a branch into a goto if it has only one successor and it is
+ %% safe to do so.
+ case ordsets:from_list(successors(NewI)) of
[Label] ->
Goto = mk_goto(Label),
- case I of
- #icode_type{} -> Goto;
+ case NewI of
#icode_if{} -> Goto;
#icode_switch_tuple_arity{} -> Goto;
#icode_switch_val{} -> Goto;
- _ -> I
+ #icode_type{} -> Goto;
+ _ -> NewI
end;
- _ -> I
+ _ -> NewI
end.
%%
diff --git a/lib/hipe/util/hipe_digraph.erl b/lib/hipe/util/hipe_digraph.erl
index a62e913fe5..fcfaa64684 100644
--- a/lib/hipe/util/hipe_digraph.erl
+++ b/lib/hipe/util/hipe_digraph.erl
@@ -1,20 +1,20 @@
%% -*- erlang-indent-level: 2 -*-
%%
%% %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,6 +30,8 @@
from_list/1, to_list/1, get_parents/2, get_children/2]).
-export([reverse_preorder_sccs/1]).
+-export_type([hdg/0]).
+
%%------------------------------------------------------------------------
-type ordset(T) :: [T]. % XXX: temporarily
diff --git a/lib/ic/doc/src/Makefile b/lib/ic/doc/src/Makefile
index 26d0932a95..8eda436a24 100644
--- a/lib/ic/doc/src/Makefile
+++ b/lib/ic/doc/src/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%
#
#
@@ -211,7 +211,11 @@ $(HTMLDIR)/%.gif: %.gif
ifdef DOCSUPPORT
+ifneq (,$(JAVA))
docs: pdf html man $(JAVADOC_GENERATED_FILES)
+else
+docs: pdf html man
+endif
$(TOP_PDF_FILE): $(XML_FILES)
@@ -301,6 +305,7 @@ release_docs_spec: docs
$(INSTALL_DATA) $(GIF_FILES) $(EXTRA_FILES) $(HTML_FILES) \
$(RELSYSDIR)/doc/html
$(INSTALL_DATA) $(INFO_FILE) $(RELSYSDIR)
+ifneq (,$(JAVA))
$(INSTALL_DIR) $(RELSYSDIR)/doc/html/java
$(INSTALL_DIR) $(RELSYSDIR)/doc/html/java/resources
$(INSTALL_DIR) $(RELSYSDIR)/doc/html/java/com
@@ -313,6 +318,7 @@ release_docs_spec: docs
$(RELSYSDIR)/doc/html/java/resources
$(INSTALL_DATA) $(JAVADOC_PACK_HTML_FILES) \
$(RELSYSDIR)/doc/html/java/com/ericsson/otp/ic
+endif
$(INSTALL_DIR) $(RELEASE_PATH)/man/man3
$(INSTALL_DATA) $(MAN3_FILES) $(RELEASE_PATH)/man/man3
diff --git a/lib/ic/doc/src/notes.xml b/lib/ic/doc/src/notes.xml
index dbafde7b4b..6684547572 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>
@@ -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>IDL Compiler Release Notes</title>
@@ -31,6 +31,22 @@
</header>
<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>
diff --git a/lib/ic/vsn.mk b/lib/ic/vsn.mk
index e0fccf4889..4aa2a04b60 100644
--- a/lib/ic/vsn.mk
+++ b/lib/ic/vsn.mk
@@ -1,6 +1,8 @@
-IC_VSN = 4.2.24
+IC_VSN = 4.2.25
-TICKETS = OTP-8307 \
+TICKETS = OTP-8639
+
+TICKETS_4.2.24 = OTP-8307 \
OTP-8353 \
OTP-8354 \
OTP-8355
diff --git a/lib/inets/doc/src/http_server.xml b/lib/inets/doc/src/http_server.xml
index 01e0b47d37..68dfd1add0 100644
--- a/lib/inets/doc/src/http_server.xml
+++ b/lib/inets/doc/src/http_server.xml
@@ -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>
@@ -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>
@@ -337,6 +344,8 @@ UserName:Password
</item>
</list>
</section>
+
+ <marker id="dynamic_we_pages"></marker>
</section>
<section>
@@ -434,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>
@@ -467,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>
diff --git a/lib/inets/doc/src/notes.xml b/lib/inets/doc/src/notes.xml
index 3216b0c2cd..fed42291ab 100644
--- a/lib/inets/doc/src/notes.xml
+++ b/lib/inets/doc/src/notes.xml
@@ -32,6 +32,61 @@
<file>notes.xml</file>
</header>
+ <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>
diff --git a/lib/inets/src/http_client/httpc_cookie.erl b/lib/inets/src/http_client/httpc_cookie.erl
index 586701b4a1..4d61f82b5a 100644
--- a/lib/inets/src/http_client/httpc_cookie.erl
+++ b/lib/inets/src/http_client/httpc_cookie.erl
@@ -476,13 +476,13 @@ 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.
+%% 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(Cookie1, "expires=") of
+ case inets_regexp:match(string:to_lower(Cookie1), "expires=") of
{_, _, _} ->
fix_netscape_cookie(Rest, [Cookie1 ++ Cookie2 | Acc]);
nomatch ->
diff --git a/lib/inets/src/http_lib/http_util.erl b/lib/inets/src/http_lib/http_util.erl
index ddb58c7116..4f1147176c 100644
--- a/lib/inets/src/http_lib/http_util.erl
+++ b/lib/inets/src/http_lib/http_util.erl
@@ -38,13 +38,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]),
@@ -54,12 +120,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]),
@@ -68,17 +134,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;
@@ -141,7 +207,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) ->
@@ -163,7 +229,9 @@ 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]).
diff --git a/lib/inets/src/http_server/httpd_instance_sup.erl b/lib/inets/src/http_server/httpd_instance_sup.erl
index 0aaeb838c2..baa60d318c 100644
--- a/lib/inets/src/http_server/httpd_instance_sup.erl
+++ b/lib/inets/src/http_server/httpd_instance_sup.erl
@@ -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),
diff --git a/lib/inets/src/http_server/httpd_sup.erl b/lib/inets/src/http_server/httpd_sup.erl
index 3399f78b53..1507c6852a 100644
--- a/lib/inets/src/http_server/httpd_sup.erl
+++ b/lib/inets/src/http_server/httpd_sup.erl
@@ -185,14 +185,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..cfad79638f 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-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, 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,23 +755,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/inets_app/inets.appup.src b/lib/inets/src/inets_app/inets.appup.src
index dfdfb41373..718f37b09e 100644
--- a/lib/inets/src/inets_app/inets.appup.src
+++ b/lib/inets/src/inets_app/inets.appup.src
@@ -18,16 +18,26 @@
{"%VSN%",
[
+ {"5.3.2",
+ [
+ {load_module, http_util, soft_purge, soft_purge, []},
+ {load_module, httpc_cookie, soft_purge, soft_purge, []}
+ ]
+ },
{"5.3.1",
[
+ {load_module, http_util, soft_purge, soft_purge, []},
{load_module, httpc, soft_purge, soft_purge, []},
+ {load_module, httpc_cookie, soft_purge, soft_purge, []},
{update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
{update, httpc_manager, soft, soft_purge, soft_purge, []}
]
},
{"5.3",
[
+ {load_module, http_util, soft_purge, soft_purge, []},
{load_module, httpc, soft_purge, soft_purge, []},
+ {load_module, httpc_cookie, soft_purge, soft_purge, []},
{update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
{update, httpc_manager, soft, soft_purge, soft_purge, []},
{load_module, mod_esi, soft_purge, soft_purge, []}
@@ -50,16 +60,26 @@
}
],
[
+ {"5.3.2",
+ [
+ {load_module, http_util, soft_purge, soft_purge, []},
+ {load_module, httpc_cookie, soft_purge, soft_purge, []}
+ ]
+ },
{"5.3.1",
[
+ {load_module, http_util, soft_purge, soft_purge, []},
{load_module, httpc, soft_purge, soft_purge, []},
+ {load_module, httpc_cookie, soft_purge, soft_purge, []},
{update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
{update, httpc_manager, soft, soft_purge, soft_purge, []}
]
},
{"5.3",
[
+ {load_module, http_util, soft_purge, soft_purge, []},
{load_module, httpc, soft_purge, soft_purge, []},
+ {load_module, httpc_cookie, soft_purge, soft_purge, []},
{update, httpc_handler, soft, soft_purge, soft_purge, [httpc_manager]},
{update, httpc_manager, soft, soft_purge, soft_purge, []},
{load_module, mod_esi, soft_purge, soft_purge, []}
diff --git a/lib/inets/src/inets_app/inets.erl b/lib/inets/src/inets_app/inets.erl
index 7e3f862ee7..f1fa5fd997 100644
--- a/lib/inets/src/inets_app/inets.erl
+++ b/lib/inets/src/inets_app/inets.erl
@@ -533,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
diff --git a/lib/inets/test/http_format_SUITE.erl b/lib/inets/test/http_format_SUITE.erl
index 9559317640..79945f0f4d 100644
--- a/lib/inets/test/http_format_SUITE.erl
+++ b/lib/inets/test/http_format_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%
%%
%%
@@ -567,6 +567,12 @@ convert_netscapecookie_date(Config) when is_list(Config) ->
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.
%%--------------------------------------------------------------------
diff --git a/lib/inets/vsn.mk b/lib/inets/vsn.mk
index 7776bef0a5..ac20fa7bb7 100644
--- a/lib/inets/vsn.mk
+++ b/lib/inets/vsn.mk
@@ -18,11 +18,15 @@
# %CopyrightEnd%
APPLICATION = inets
-INETS_VSN = 5.3.2
+INETS_VSN = 5.3.3
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(INETS_VSN)$(PRE_VSN)"
-TICKETS = OTP-8542 OTP-8607
+TICKETS = OTP-8609 OTP-8610 OTP-8624
+
+TICKETS_5_3_2 = \
+ OTP-8542 \
+ OTP-8607
TICKETS_5_3_1 = \
OTP-8508 \
@@ -42,7 +46,14 @@ TICKETS_5_3 = \
OTP-8359 \
OTP-8371
-TICKETS_5_2 = OTP-8204 OTP-8206 OTP-8247 OTP-8248 OTP-8249 OTP-8258 OTP-8280
+TICKETS_5_2 = \
+ OTP-8204 \
+ OTP-8206 \
+ OTP-8247 \
+ OTP-8248 \
+ OTP-8249 \
+ OTP-8258 \
+ OTP-8280
TICKETS_5_1_3 = OTP-8154
diff --git a/lib/kernel/doc/src/file.xml b/lib/kernel/doc/src/file.xml
index 50f9722a1c..382262d1ee 100644
--- a/lib/kernel/doc/src/file.xml
+++ b/lib/kernel/doc/src/file.xml
@@ -62,6 +62,25 @@ time() = {{Year, Month, Day}, {Hour, Minute, Second}}
</section>
<funcs>
<func>
+ <name>advise(IoDevice, Offset, Length, Advise) -> ok | {error, Reason}</name>
+ <fsummary>Predeclare an access pattern for file data</fsummary>
+ <type>
+ <v>IoDevice = io_device()</v>
+ <v>Offset = int()</v>
+ <v>Length = int()</v>
+ <v>Advise = posix_file_advise()</v>
+ <v>posix_file_advise() = normal | sequential | random | no_reuse
+ | will_need | dont_need</v>
+ <v>Reason = ext_posix()</v>
+ </type>
+ <desc>
+ <p><c>advise/4</c> can be used to announce an intention to access file
+ data in a specific pattern in the future, thus allowing the
+ operating system to perform appropriate optimizations.</p>
+ <p>On some platforms, this function might have no effect.</p>
+ </desc>
+ </func>
+ <func>
<name>change_group(Filename, Gid) -> ok | {error, Reason}</name>
<fsummary>Change group of a file</fsummary>
<type>
@@ -1641,6 +1660,33 @@ f.txt: {person, "kalle", 25}.
</desc>
</func>
<func>
+ <name>datasync(IoDevice) -> ok | {error, Reason}</name>
+ <fsummary>Synchronizes the in-memory data of a file, ignoring most of its metadata, with that on the physical medium</fsummary>
+ <type>
+ <v>IoDevice = io_device()</v>
+ <v>Reason = ext_posix() | terminated</v>
+ </type>
+ <desc>
+ <p>Makes sure that any buffers kept by the operating system
+ (not by the Erlang runtime system) are written to disk. In
+ many ways it's resembles fsync but it not requires to update
+ some of file's metadata such as the access time. On
+ some platforms, this function might have no effect.</p>
+ <p>Applications that access databases or log files often write
+ a tiny data fragment (e.g., one line in a log file) and then
+ call fsync() immediately in order to ensure that the written
+ data is physically stored on the harddisk. Unfortunately, fsync()
+ will always initiate two write operations: one for the newly
+ written data and another one in order to update the modification
+ time stored in the inode. If the modification time is not a part
+ of the transaction concept fdatasync() can be used to avoid
+ unnecessary inode disk write operations.</p>
+ <p>Available only in some POSIX systems. This call results in a
+ call to fsync(), or has no effect, in systems not implementing
+ the fdatasync syscall.</p>
+ </desc>
+ </func>
+ <func>
<name>truncate(IoDevice) -> ok | {error, Reason}</name>
<fsummary>Truncate a file</fsummary>
<type>
diff --git a/lib/kernel/src/code.erl b/lib/kernel/src/code.erl
index affa5fc0fd..42d4818f08 100644
--- a/lib/kernel/src/code.erl
+++ b/lib/kernel/src/code.erl
@@ -66,6 +66,8 @@
set_primary_archive/3,
clash/0]).
+-export_type([load_error_rsn/0, load_ret/0]).
+
-include_lib("kernel/include/file.hrl").
%% User interface.
diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl
index a2937d60b8..f0d54a2f3e 100644
--- a/lib/kernel/src/dist_util.erl
+++ b/lib/kernel/src/dist_util.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%
%%
%%%----------------------------------------------------------------------
@@ -564,7 +564,7 @@ recv_challenge(#hs_data{socket=Socket,other_node=Node,
case Recv(Socket, 0, infinity) of
{ok,[$n,V1,V0,Fl1,Fl2,Fl3,Fl4,CA3,CA2,CA1,CA0 | Ns]} ->
Flags = ?u32(Fl1,Fl2,Fl3,Fl4),
- case {list_to_existing_atom(Ns),?u16(V1,V0)} of
+ try {list_to_existing_atom(Ns),?u16(V1,V0)} of
{Node,Version} ->
Challenge = ?u32(CA3,CA2,CA1,CA0),
?trace("recv: node=~w, challenge=~w version=~w\n",
@@ -572,6 +572,9 @@ recv_challenge(#hs_data{socket=Socket,other_node=Node,
{Flags,Challenge};
_ ->
?shutdown(no_node)
+ catch
+ error:badarg ->
+ ?shutdown(no_node)
end;
_ ->
?shutdown(no_node)
diff --git a/lib/kernel/src/file.erl b/lib/kernel/src/file.erl
index 46ffa9d708..4f49371970 100644
--- a/lib/kernel/src/file.erl
+++ b/lib/kernel/src/file.erl
@@ -36,11 +36,11 @@
%% Specialized
-export([ipread_s32bu_p32bu/3]).
%% Generic file contents.
--export([open/2, close/1,
+-export([open/2, close/1, advise/4,
read/2, write/2,
pread/2, pread/3, pwrite/2, pwrite/3,
read_line/1,
- position/2, truncate/1, sync/1,
+ position/2, truncate/1, datasync/1, sync/1,
copy/2, copy/3]).
%% High level operations
-export([consult/1, path_consult/2]).
@@ -61,6 +61,9 @@
-export([ipread_s32bu_p32bu_int/3]).
+%% Types that can be used from other modules -- alphabetically ordered.
+-export_type([date_time/0, fd/0, file_info/0, filename/0, io_device/0,
+ name/0, posix/0]).
%%% Includes and defines
-include("file.hrl").
@@ -89,6 +92,8 @@
-type date() :: {pos_integer(), pos_integer(), pos_integer()}.
-type time() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
-type date_time() :: {date(), time()}.
+-type posix_file_advise() :: 'normal' | 'sequential' | 'random' | 'no_reuse' |
+ 'will_need' | 'dont_need'.
%%%-----------------------------------------------------------------
%%% General functions
@@ -352,10 +357,22 @@ close(#file_descriptor{module = Module} = Handle) ->
close(_) ->
{error, badarg}.
+-spec advise(File :: io_device(), Offset :: integer(),
+ Length :: integer(), Advise :: posix_file_advise()) ->
+ 'ok' | {'error', posix()}.
+
+advise(File, Offset, Length, Advise) when is_pid(File) ->
+ R = file_request(File, {advise, Offset, Length, Advise}),
+ wait_file_reply(File, R);
+advise(#file_descriptor{module = Module} = Handle, Offset, Length, Advise) ->
+ Module:advise(Handle, Offset, Length, Advise);
+advise(_, _, _, _) ->
+ {error, badarg}.
+
-spec read(File :: io_device(), Size :: non_neg_integer()) ->
'eof' | {'ok', [char()] | binary()} | {'error', posix()}.
-read(File, Sz) when is_pid(File), is_integer(Sz), Sz >= 0 ->
+read(File, Sz) when (is_pid(File) orelse is_atom(File)), is_integer(Sz), Sz >= 0 ->
case io:request(File, {get_chars, '', Sz}) of
Data when is_list(Data); is_binary(Data) ->
{ok, Data};
@@ -371,7 +388,7 @@ read(_, _) ->
-spec read_line(File :: io_device()) ->
'eof' | {'ok', [char()] | binary()} | {'error', posix()}.
-read_line(File) when is_pid(File) ->
+read_line(File) when (is_pid(File) orelse is_atom(File)) ->
case io:request(File, {get_line, ''}) of
Data when is_list(Data); is_binary(Data) ->
{ok, Data};
@@ -425,7 +442,7 @@ pread(_, _, _) ->
-spec write(File :: io_device(), Byte :: iodata()) ->
'ok' | {'error', posix()}.
-write(File, Bytes) when is_pid(File) ->
+write(File, Bytes) when (is_pid(File) orelse is_atom(File)) ->
case make_binary(Bytes) of
Bin when is_binary(Bin) ->
io:request(File, {put_chars,Bin});
@@ -472,6 +489,16 @@ pwrite(#file_descriptor{module = Module} = Handle, Offs, Bytes) ->
pwrite(_, _, _) ->
{error, badarg}.
+-spec datasync(File :: io_device()) -> 'ok' | {'error', posix()}.
+
+datasync(File) when is_pid(File) ->
+ R = file_request(File, datasync),
+ wait_file_reply(File, R);
+datasync(#file_descriptor{module = Module} = Handle) ->
+ Module:datasync(Handle);
+datasync(_) ->
+ {error, badarg}.
+
-spec sync(File :: io_device()) -> 'ok' | {'error', posix()}.
sync(File) when is_pid(File) ->
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index 3ac35a209d..39dc32bb79 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -198,6 +198,14 @@ io_reply(From, ReplyAs, Reply) ->
%%%-----------------------------------------------------------------
%%% file requests
+file_request({advise,Offset,Length,Advise},
+ #state{handle=Handle}=State) ->
+ case ?PRIM_FILE:advise(Handle, Offset, Length, Advise) of
+ {error,_}=Reply ->
+ {stop,normal,Reply,State};
+ Reply ->
+ {reply,Reply,State}
+ end;
file_request({pread,At,Sz},
#state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
case position(Handle, At, Buf) of
@@ -219,6 +227,14 @@ file_request({pwrite,At,Data},
Reply ->
std_reply(Reply, State)
end;
+file_request(datasync,
+ #state{handle=Handle}=State) ->
+ case ?PRIM_FILE:datasync(Handle) of
+ {error,_}=Reply ->
+ {stop,normal,Reply,State};
+ Reply ->
+ {reply,Reply,State}
+ end;
file_request(sync,
#state{handle=Handle}=State) ->
case ?PRIM_FILE:sync(Handle) of
diff --git a/lib/kernel/src/group.erl b/lib/kernel/src/group.erl
index a45ba34eae..f92c6f7208 100644
--- a/lib/kernel/src/group.erl
+++ b/lib/kernel/src/group.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(group).
@@ -477,15 +477,15 @@ get_line(Chars, Pbs, Drv, Encoding) ->
get_line1(edlin:edit_line(Chars, Cont), Drv, new_stack(get(line_buffer)),
Encoding).
-get_line1({done,Line,Rest,Rs}, Drv, _Ls, _Encoding) ->
+get_line1({done,Line,Rest,Rs}, Drv, Ls, _Encoding) ->
send_drv_reqs(Drv, Rs),
- put(line_buffer, [Line|lists:delete(Line, get(line_buffer))]),
+ save_line_buffer(Line, get_lines(Ls)),
{done,Line,Rest};
get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls0, Encoding)
when ((Mode =:= none) and (Char =:= $\^P))
or ((Mode =:= meta_left_sq_bracket) and (Char =:= $A)) ->
send_drv_reqs(Drv, Rs),
- case up_stack(Ls0) of
+ case up_stack(save_line(Ls0, edlin:current_line(Cont))) of
{none,_Ls} ->
send_drv(Drv, beep),
get_line1(edlin:edit_line(Cs, Cont), Drv, Ls0, Encoding);
@@ -498,14 +498,14 @@ get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls0, Encoding)
Drv,
Ls, Encoding)
end;
-get_line1({undefined,{_A,Mode,Char},_Cs,Cont,Rs}, Drv, Ls0, Encoding)
+get_line1({undefined,{_A,Mode,Char},Cs,Cont,Rs}, Drv, Ls0, Encoding)
when ((Mode =:= none) and (Char =:= $\^N))
or ((Mode =:= meta_left_sq_bracket) and (Char =:= $B)) ->
send_drv_reqs(Drv, Rs),
- case down_stack(Ls0) of
- {none,Ls} ->
- send_drv_reqs(Drv, edlin:erase_line(Cont)),
- get_line1(edlin:start(edlin:prompt(Cont)), Drv, Ls, Encoding);
+ case down_stack(save_line(Ls0, edlin:current_line(Cont))) of
+ {none,_Ls} ->
+ send_drv(Drv, beep),
+ get_line1(edlin:edit_line(Cs, Cont), Drv, Ls0, Encoding);
{Lcs,Ls} ->
send_drv_reqs(Drv, edlin:erase_line(Cont)),
{more_chars,Ncont,Nrs} = edlin:start(edlin:prompt(Cont)),
@@ -627,6 +627,28 @@ down_stack({stack,U,{},[]}) ->
down_stack({stack,U,C,D}) ->
down_stack({stack,[C|U],{},D}).
+save_line({stack, U, {}, []}, Line) ->
+ {stack, U, {}, [Line]};
+save_line({stack, U, _L, D}, Line) ->
+ {stack, U, Line, D}.
+
+get_lines({stack, U, {}, []}) ->
+ U;
+get_lines({stack, U, {}, D}) ->
+ tl(lists:reverse(D, U));
+get_lines({stack, U, L, D}) ->
+ get_lines({stack, U, {}, [L|D]}).
+
+save_line_buffer("\n", Lines) ->
+ save_line_buffer(Lines);
+save_line_buffer(Line, [Line|_Lines]=Lines) ->
+ save_line_buffer(Lines);
+save_line_buffer(Line, Lines) ->
+ save_line_buffer([Line|Lines]).
+
+save_line_buffer(Lines) ->
+ put(line_buffer, Lines).
+
%% This is get_line without line editing (except for backspace) and
%% without echo.
get_password_line(Chars, Drv) ->
diff --git a/lib/kernel/src/inet.erl b/lib/kernel/src/inet.erl
index eb503235d8..93d75321ba 100644
--- a/lib/kernel/src/inet.erl
+++ b/lib/kernel/src/inet.erl
@@ -62,6 +62,8 @@
%% timer interface
-export([start_timer/1, timeout/1, timeout/2, stop_timer/1]).
+-export_type([ip_address/0, socket/0]).
+
%% imports
-import(lists, [append/1, duplicate/2, filter/2, foldl/3]).
diff --git a/lib/kernel/src/inet_dns.erl b/lib/kernel/src/inet_dns.erl
index 669a361c9d..1289e176c7 100644
--- a/lib/kernel/src/inet_dns.erl
+++ b/lib/kernel/src/inet_dns.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_dns).
@@ -129,27 +129,33 @@ do_decode(<<Id:16,
RA:1,PR:1,_:2,Rcode:4,
QdCount:16,AnCount:16,NsCount:16,ArCount:16,
QdBuf/binary>>=Buffer) ->
- {AnBuf,QdList} = decode_query_section(QdBuf,QdCount,Buffer),
- {NsBuf,AnList} = decode_rr_section(AnBuf,AnCount,Buffer),
- {ArBuf,NsList} = decode_rr_section(NsBuf,NsCount,Buffer),
- {Rest,ArList} = decode_rr_section(ArBuf,ArCount,Buffer),
+ {AnBuf,QdList,QdTC} = decode_query_section(QdBuf,QdCount,Buffer),
+ {NsBuf,AnList,AnTC} = decode_rr_section(AnBuf,AnCount,Buffer),
+ {ArBuf,NsList,NsTC} = decode_rr_section(NsBuf,NsCount,Buffer),
+ {Rest,ArList,ArTC} = decode_rr_section(ArBuf,ArCount,Buffer),
case Rest of
<<>> ->
+ HdrTC = decode_boolean(TC),
DnsHdr =
#dns_header{id=Id,
qr=decode_boolean(QR),
opcode=decode_opcode(Opcode),
aa=decode_boolean(AA),
- tc=decode_boolean(TC),
+ tc=HdrTC,
rd=decode_boolean(RD),
ra=decode_boolean(RA),
pr=decode_boolean(PR),
rcode=Rcode},
- #dns_rec{header=DnsHdr,
- qdlist=QdList,
- anlist=AnList,
- nslist=NsList,
- arlist=ArList};
+ case QdTC or AnTC or NsTC or ArTC of
+ true when not HdrTC ->
+ throw(?DECODE_ERROR);
+ _ ->
+ #dns_rec{header=DnsHdr,
+ qdlist=QdList,
+ anlist=AnList,
+ nslist=NsList,
+ arlist=ArList}
+ end;
_ ->
%% Garbage data after DNS message
throw(?DECODE_ERROR)
@@ -161,8 +167,10 @@ do_decode(_) ->
decode_query_section(Bin, N, Buffer) ->
decode_query_section(Bin, N, Buffer, []).
+decode_query_section(<<>>=Rest, N, _Buffer, Qs) ->
+ {Rest,reverse(Qs),N =/= 0};
decode_query_section(Rest, 0, _Buffer, Qs) ->
- {Rest,reverse(Qs)};
+ {Rest,reverse(Qs),false};
decode_query_section(Bin, N, Buffer, Qs) ->
case decode_name(Bin, Buffer) of
{<<Type:16,Class:16,Rest/binary>>,Name} ->
@@ -179,8 +187,10 @@ decode_query_section(Bin, N, Buffer, Qs) ->
decode_rr_section(Bin, N, Buffer) ->
decode_rr_section(Bin, N, Buffer, []).
+decode_rr_section(<<>>=Rest, N, _Buffer, RRs) ->
+ {Rest,reverse(RRs),N =/= 0};
decode_rr_section(Rest, 0, _Buffer, RRs) ->
- {Rest,reverse(RRs)};
+ {Rest,reverse(RRs),false};
decode_rr_section(Bin, N, Buffer, RRs) ->
case decode_name(Bin, Buffer) of
{<<T:16/unsigned,C:16/unsigned,TTL:4/binary,
diff --git a/lib/kernel/src/inet_res.erl b/lib/kernel/src/inet_res.erl
index 9b9e078898..de0f23bf24 100644
--- a/lib/kernel/src/inet_res.erl
+++ b/lib/kernel/src/inet_res.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%
%%
%% RFC 1035, 2671, 2782, 2915.
@@ -592,6 +592,7 @@ query_retries(_Q, _NSs, _Timer, Retry, Retry, S) ->
query_retries(Q, NSs, Timer, Retry, I, S0) ->
Num = length(NSs),
if Num =:= 0 ->
+ udp_close(S0),
{error,timeout};
true ->
case query_nss(Q, NSs, Timer, Retry, I, S0, []) of
diff --git a/lib/kernel/src/net_kernel.erl b/lib/kernel/src/net_kernel.erl
index 3afaedf274..0e17c059e5 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).
@@ -72,7 +72,7 @@
-export([publish_on_node/1, update_publish_nodes/1]).
-%% Internal Exports
+%% Internal Exports
-export([do_spawn/3,
spawn_func/6,
ticker/2,
@@ -94,7 +94,7 @@
connecttime, %% the connection setuptime.
connections, %% table of connections
conn_owners = [], %% List of connection owner pids,
- pend_owners = [], %% List of potential owners
+ pend_owners = [], %% List of potential owners
listen, %% list of #listen
allowed, %% list of allowed nodes in a restricted system
verbose = 0, %% level of verboseness
@@ -232,7 +232,7 @@ do_connect(Node, Type, WaitForBarred) -> %% Type = normal | hidden
%% "connected from other end.~n",[Node]),
true;
{Pid, false} ->
- ?connect_failure(Node,{barred_connection,
+ ?connect_failure(Node,{barred_connection,
ets:lookup(sys_dist, Node)}),
%%io:format("Net Kernel: barred connection (~p) "
%% "- failure.~n",[Node]),
@@ -244,12 +244,12 @@ do_connect(Node, Type, WaitForBarred) -> %% Type = normal | hidden
{ok, never} ->
?connect_failure(Node,{dist_auto_connect,never}),
false;
- % This might happen due to connection close
+ % This might happen due to connection close
% not beeing propagated to user space yet.
- % Save the day by just not connecting...
+ % Save the day by just not connecting...
{ok, once} when Else =/= [],
(hd(Else))#connection.state =:= up ->
- ?connect_failure(Node,{barred_connection,
+ ?connect_failure(Node,{barred_connection,
ets:lookup(sys_dist, Node)}),
false;
_ ->
@@ -276,8 +276,8 @@ passive_connect_monitor(Parent, Node) ->
Parent ! {self(),true}
end
end.
-
-%% If the net_kernel isn't running we ignore all requests to the
+
+%% If the net_kernel isn't running we ignore all requests to the
%% kernel, thus basically accepting them :-)
request(Req) ->
case whereis(net_kernel) of
@@ -302,7 +302,7 @@ start_link([Name, LongOrShortNames]) ->
start_link([Name, LongOrShortNames, 15000]);
start_link([Name, LongOrShortNames, Ticktime]) ->
- case gen_server:start_link({local, net_kernel}, net_kernel,
+ case gen_server:start_link({local, net_kernel}, net_kernel,
{Name, LongOrShortNames, Ticktime}, []) of
{ok, Pid} ->
{ok, Pid};
@@ -313,7 +313,7 @@ start_link([Name, LongOrShortNames, Ticktime]) ->
end.
%% auth:get_cookie should only be able to return an atom
-%% tuple cookies are unknowns
+%% tuple cookies are unknowns
init({Name, LongOrShortNames, TickT}) ->
process_flag(trap_exit,true),
@@ -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,74 +376,75 @@ 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.
-%%
+%%
handle_call({spawn,M,F,A,Gleader},{From,Tag},State) when is_pid(From) ->
do_spawn([no_link,{From,Tag},M,F,A,Gleader],[],State);
-%%
+%%
%% The spawn_link/4 BIF ends up here.
-%%
+%%
handle_call({spawn_link,M,F,A,Gleader},{From,Tag},State) when is_pid(From) ->
do_spawn([link,{From,Tag},M,F,A,Gleader],[],State);
-%%
+%%
%% The spawn_opt/5 BIF ends up here.
-%%
+%%
handle_call({spawn_opt,M,F,A,O,L,Gleader},{From,Tag},State) when is_pid(From) ->
do_spawn([L,{From,Tag},M,F,A,Gleader],O,State);
-%%
+%%
%% 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)
+%%
+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,18 @@ 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,From,_},
_,
#state{tick = #tick_change{time = T}} = State) ->
- {reply, {ongoing_change_to, T}, State}.
+ async_reply({reply, {ongoing_change_to, T}, State}, From);
+
+handle_call(_Msg, _From, State) ->
+ {noreply, State}.
%% ------------------------------------------------------------
%% handle_cast.
@@ -568,7 +574,7 @@ handle_info({accept,AcceptPid,Socket,Family,Proto}, State) ->
%%
%% A node has successfully been connected.
%%
-handle_info({SetupPid, {nodeup,Node,Address,Type,Immediate}},
+handle_info({SetupPid, {nodeup,Node,Address,Type,Immediate}},
State) ->
case {Immediate, ets:lookup(sys_dist, Node)} of
{true, [Conn]} when Conn#connection.state =:= pending,
@@ -656,7 +662,7 @@ handle_info({From,registered_send,To,Mess},State) ->
send(From,To,Mess),
{noreply,State};
-%% badcookies SHOULD not be sent
+%% badcookies SHOULD not be sent
%% (if someone does erlang:set_cookie(node(),foo) this may be)
handle_info({From,badcookie,_To,_Mess}, State) ->
error_logger:error_msg("~n** Got OLD cookie from ~w~n",
@@ -704,7 +710,7 @@ handle_info(X, State) ->
%% 4. The ticker process.
%% (5. Garbage pid.)
%%
-%% The process type function that handled the process throws
+%% The process type function that handled the process throws
%% the handle_info return value !
%% -----------------------------------------------------------
@@ -994,9 +1000,9 @@ ticker(Kernel, Tick) when is_integer(Tick) ->
ticker_loop(Kernel, Tick).
to_integer(T) when is_integer(T) -> T;
-to_integer(T) when is_atom(T) ->
+to_integer(T) when is_atom(T) ->
list_to_integer(atom_to_list(T));
-to_integer(T) when is_list(T) ->
+to_integer(T) when is_list(T) ->
list_to_integer(T).
ticker_loop(Kernel, Tick) ->
@@ -1004,7 +1010,7 @@ ticker_loop(Kernel, Tick) ->
{new_ticktime, NewTick} ->
?tckr_dbg({ticker_changed_time, Tick, NewTick}),
?MODULE:ticker_loop(Kernel, NewTick)
- after Tick ->
+ after Tick ->
Kernel ! tick,
?MODULE:ticker_loop(Kernel, Tick)
end.
@@ -1052,7 +1058,7 @@ send(_From,To,Mess) ->
-ifdef(UNUSED).
safesend(Name,Mess) when is_atom(Name) ->
- case whereis(Name) of
+ case whereis(Name) of
undefined ->
Mess;
P when is_pid(P) ->
@@ -1063,11 +1069,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.
@@ -1079,11 +1086,11 @@ do_spawn(SpawnFuncArgs, SpawnOpts, State) ->
spawn_func(link,{From,Tag},M,F,A,Gleader) ->
link(From),
- gen_server:reply({From,Tag},self()), %% ahhh
+ async_gen_server_reply({From,Tag},self()), %% ahhh
group_leader(Gleader,self()),
apply(M,F,A);
spawn_func(_,{From,Tag},M,F,A,Gleader) ->
- gen_server:reply({From,Tag},self()), %% ahhh
+ async_gen_server_reply({From,Tag},self()), %% ahhh
group_leader(Gleader,self()),
apply(M,F,A).
@@ -1145,7 +1152,7 @@ get_proto_mod(Family,Protocol,[L|Ls]) ->
true ->
get_proto_mod(Family,Protocol,Ls)
end;
-get_proto_mod(_Family, _Protocol, []) ->
+get_proto_mod(_Family, _Protocol, []) ->
error.
%% -------- Initialisation functions ------------------------
@@ -1156,9 +1163,9 @@ init_node(Name, LongOrShortNames) ->
case create_name(Name, LongOrShortNames, 1) of
{ok,Node} ->
case start_protos(list_to_atom(NameWithoutHost),Node) of
- {ok, Ls} ->
+ {ok, Ls} ->
{ok, Node, Ls};
- Error ->
+ Error ->
Error
end;
Error ->
@@ -1167,9 +1174,9 @@ init_node(Name, LongOrShortNames) ->
%% Create the node name
create_name(Name, LongOrShortNames, Try) ->
- put(longnames, case LongOrShortNames of
- shortnames -> false;
- longnames -> true
+ put(longnames, case LongOrShortNames of
+ shortnames -> false;
+ longnames -> true
end),
{Head,Host1} = create_hostpart(Name, LongOrShortNames),
case Host1 of
@@ -1218,7 +1225,7 @@ create_hostpart(Name, LongOrShortNames) ->
{Head,Host1}.
%%
-%%
+%%
%%
protocol_childspecs() ->
case init:get_argument(proto_dist) of
@@ -1228,7 +1235,7 @@ protocol_childspecs() ->
protocol_childspecs(["inet_tcp"])
end.
-protocol_childspecs([]) ->
+protocol_childspecs([]) ->
[];
protocol_childspecs([H|T]) ->
Mod = list_to_atom(H ++ "_dist"),
@@ -1238,15 +1245,15 @@ protocol_childspecs([H|T]) ->
_ ->
protocol_childspecs(T)
end.
-
-
+
+
%%
%% epmd_module() -> module_name of erl_epmd or similar gen_server_module.
%%
epmd_module() ->
case init:get_argument(epmd_module) of
- {ok,[[Module]]} ->
+ {ok,[[Module]]} ->
Module;
_ ->
erl_epmd
@@ -1293,7 +1300,7 @@ start_protos(Name, [Proto | Ps], Node, Ls) ->
error_logger:info_msg("Protocol: ~p: not supported~n", [Proto]),
start_protos(Name,Ps, Node, Ls);
{'EXIT', Reason} ->
- error_logger:info_msg("Protocol: ~p: register error: ~p~n",
+ error_logger:info_msg("Protocol: ~p: register error: ~p~n",
[Proto, Reason]),
start_protos(Name,Ps, Node, Ls);
{error, duplicate_name} ->
@@ -1303,7 +1310,7 @@ start_protos(Name, [Proto | Ps], Node, Ls) ->
[Proto]),
start_protos(Name,Ps, Node, Ls);
{error, Reason} ->
- error_logger:info_msg("Protocol: ~p: register/listen error: ~p~n",
+ error_logger:info_msg("Protocol: ~p: register/listen error: ~p~n",
[Proto, Reason]),
start_protos(Name,Ps, Node, Ls)
end;
@@ -1409,7 +1416,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.
@@ -1455,7 +1462,7 @@ display_info({Node, Info}, {I,O}) ->
integer_to_list(In), integer_to_list(Out), Address),
{I+In,O+Out}.
-fmt_address(undefined) ->
+fmt_address(undefined) ->
"-";
fmt_address(A) ->
case A#net_address.family of
@@ -1511,3 +1518,19 @@ 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
+ true ->
+ M;
+ false ->
+ spawn(fun() -> gen_server:reply(From, Msg) end);
+ EXIT ->
+ EXIT
+ end.
diff --git a/lib/kernel/src/os.erl b/lib/kernel/src/os.erl
index d0b498edc9..75a11a8afd 100644
--- a/lib/kernel/src/os.erl
+++ b/lib/kernel/src/os.erl
@@ -50,7 +50,7 @@ find_executable(Name, Path) ->
relative ->
find_executable1(Name, split_path(Path), Extensions);
_ ->
- case verify_executable(Name, Extensions) of
+ case verify_executable(Name, Extensions, Extensions) of
{ok, Complete} ->
Complete;
error ->
@@ -60,7 +60,7 @@ find_executable(Name, Path) ->
find_executable1(Name, [Base|Rest], Extensions) ->
Complete0 = filename:join(Base, Name),
- case verify_executable(Complete0, Extensions) of
+ case verify_executable(Complete0, Extensions, Extensions) of
{ok, Complete} ->
Complete;
error ->
@@ -69,7 +69,7 @@ find_executable1(Name, [Base|Rest], Extensions) ->
find_executable1(_Name, [], _Extensions) ->
false.
-verify_executable(Name0, [Ext|Rest]) ->
+verify_executable(Name0, [Ext|Rest], OrigExtensions) ->
Name1 = Name0 ++ Ext,
case os:type() of
vxworks ->
@@ -78,7 +78,7 @@ verify_executable(Name0, [Ext|Rest]) ->
{ok, _} ->
{ok, Name1};
_ ->
- verify_executable(Name0, Rest)
+ verify_executable(Name0, Rest, OrigExtensions)
end;
_ ->
case file:read_file_info(Name1) of
@@ -87,12 +87,30 @@ verify_executable(Name0, [Ext|Rest]) ->
%% on Unix, since we test if any execution bit is set.
{ok, Name1};
_ ->
- verify_executable(Name0, Rest)
+ verify_executable(Name0, Rest, OrigExtensions)
end
end;
-verify_executable(_, []) ->
+verify_executable(Name, [], OrigExtensions) when OrigExtensions =/= [""] -> %% Windows
+ %% Will only happen on windows, hence case insensitivity
+ case can_be_full_name(string:to_lower(Name),OrigExtensions) of
+ true ->
+ verify_executable(Name,[""],[""]);
+ _ ->
+ error
+ end;
+verify_executable(_, [], _) ->
error.
+can_be_full_name(_Name,[]) ->
+ false;
+can_be_full_name(Name,[H|T]) ->
+ case lists:suffix(H,Name) of %% Name is in lowercase, cause this is a windows thing
+ true ->
+ true;
+ _ ->
+ can_be_full_name(Name,T)
+ end.
+
split_path(Path) ->
case type() of
{win32, _} ->
@@ -119,6 +137,7 @@ reverse_element(List) ->
lists:reverse(List).
-spec extensions() -> [string()].
+%% Extensions in lower case
extensions() ->
case type() of
{win32, _} -> [".exe",".com",".cmd",".bat"];
diff --git a/lib/kernel/src/pg2.erl b/lib/kernel/src/pg2.erl
index cb9fec2ffe..956a900adc 100644
--- a/lib/kernel/src/pg2.erl
+++ b/lib/kernel/src/pg2.erl
@@ -251,7 +251,9 @@ terminate(_Reason, _S) ->
%%% Pid is a member of group Name.
store(List) ->
- _ = [assure_group(Name) andalso [join_group(Name, P) || P <- Members] ||
+ _ = [(assure_group(Name)
+ andalso
+ [join_group(Name, P) || P <- Members -- group_members(Name)]) ||
[Name, Members] <- List],
ok.
diff --git a/lib/kernel/src/ram_file.erl b/lib/kernel/src/ram_file.erl
index d996650948..48ea871433 100644
--- a/lib/kernel/src/ram_file.erl
+++ b/lib/kernel/src/ram_file.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(ram_file).
@@ -24,11 +24,11 @@
-export([open/2, close/1]).
-export([write/2, read/2, copy/3,
pread/2, pread/3, pwrite/2, pwrite/3,
- position/2, truncate/1, sync/1]).
+ position/2, truncate/1, datasync/1, sync/1]).
%% Specialized file operations
-export([get_size/1, get_file/1, set_file/2, get_file_close/1]).
--export([compress/1, uncompress/1, uuencode/1, uudecode/1]).
+-export([compress/1, uncompress/1, uuencode/1, uudecode/1, advise/4]).
-export([open_mode/1]). %% used by ftp-file
@@ -60,6 +60,7 @@
-define(RAM_FILE_TRUNCATE, 14).
-define(RAM_FILE_PREAD, 17).
-define(RAM_FILE_PWRITE, 18).
+-define(RAM_FILE_FDATASYNC, 19).
%% Other operations
-define(RAM_FILE_GET, 30).
@@ -70,6 +71,7 @@
-define(RAM_FILE_UUENCODE, 35).
-define(RAM_FILE_UUDECODE, 36).
-define(RAM_FILE_SIZE, 37).
+-define(RAM_FILE_ADVISE, 38).
%% Open modes for RAM_FILE_OPEN
-define(RAM_FILE_MODE_READ, 1).
@@ -90,6 +92,14 @@
-define(RAM_FILE_RESP_NUMBER, 3).
-define(RAM_FILE_RESP_INFO, 4).
+%% POSIX file advises
+-define(POSIX_FADV_NORMAL, 0).
+-define(POSIX_FADV_RANDOM, 1).
+-define(POSIX_FADV_SEQUENTIAL, 2).
+-define(POSIX_FADV_WILLNEED, 3).
+-define(POSIX_FADV_DONTNEED, 4).
+-define(POSIX_FADV_NOREUSE, 5).
+
%% --------------------------------------------------------------------------
%% Generic file contents operations.
%%
@@ -167,6 +177,8 @@ copy(#file_descriptor{module = ?MODULE} = Source,
%% XXX Should be moved down to the driver for optimization.
file:copy_opened(Source, Dest, Length).
+datasync(#file_descriptor{module = ?MODULE, data = Port}) ->
+ call_port(Port, <<?RAM_FILE_FDATASYNC>>).
sync(#file_descriptor{module = ?MODULE, data = Port}) ->
call_port(Port, <<?RAM_FILE_FSYNC>>).
@@ -349,6 +361,28 @@ uudecode(#file_descriptor{module = ?MODULE, data = Port}) ->
uudecode(#file_descriptor{}) ->
{error, enotsup}.
+advise(#file_descriptor{module = ?MODULE, data = Port}, Offset,
+ Length, Advise) ->
+ Cmd0 = <<?RAM_FILE_ADVISE, Offset:64/signed, Length:64/signed>>,
+ case Advise of
+ normal ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_NORMAL:32/signed>>);
+ random ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_RANDOM:32/signed>>);
+ sequential ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_SEQUENTIAL:32/signed>>);
+ will_need ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_WILLNEED:32/signed>>);
+ dont_need ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_DONTNEED:32/signed>>);
+ no_reuse ->
+ call_port(Port, <<Cmd0/binary, ?POSIX_FADV_NOREUSE:32/signed>>);
+ _ ->
+ {error, einval}
+ end;
+advise(#file_descriptor{}, _Offset, _Length, _Advise) ->
+ {error, enotsup}.
+
%%%-----------------------------------------------------------------
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index 1d170790a3..15bab0dccd 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -52,7 +52,7 @@
old_modes/1, new_modes/1, path_open/1, open_errors/1]).
-export([file_info/1, file_info_basic_file/1, file_info_basic_directory/1,
file_info_bad/1, file_info_times/1, file_write_file_info/1]).
--export([rename/1, access/1, truncate/1, sync/1,
+-export([rename/1, access/1, truncate/1, datasync/1, sync/1,
read_write/1, pread_write/1, append/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
-export([otp_5814/1]).
@@ -82,6 +82,10 @@
-export([read_line_1/1, read_line_2/1, read_line_3/1,read_line_4/1]).
+-export([advise/1]).
+
+-export([standard_io/1,mini_server/1]).
+
%% Debug exports
-export([create_file_slow/2, create_file/2, create_bin/2]).
-export([verify_file/2, verify_bin/3]).
@@ -101,7 +105,8 @@ all(suite) ->
compression, links, copy,
delayed_write, read_ahead, segment_read, segment_write,
ipread, pid2name, interleaved_read_write,
- otp_5814, large_file, read_line_1, read_line_2, read_line_3, read_line_4],
+ otp_5814, large_file, read_line_1, read_line_2, read_line_3, read_line_4,
+ standard_io],
fini}.
init(Config) when is_list(Config) ->
@@ -170,6 +175,85 @@ time_dist({_D1, _T1} = DT1, {_D2, _T2} = DT2) ->
- calendar:datetime_to_gregorian_seconds(DT1).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+mini_server(Parent) ->
+ receive
+ die ->
+ ok;
+ {io_request,From,To,{put_chars,Data}} ->
+ Parent ! {io_request,From,To,{put_chars,Data}},
+ From ! {io_reply, To, ok},
+ mini_server(Parent);
+ {io_request,From,To,{get_chars,'',N}} ->
+ Parent ! {io_request,From,To,{get_chars,'',N}},
+ From ! {io_reply, To, {ok, lists:duplicate(N,$a)}},
+ mini_server(Parent);
+ {io_request,From,To,{get_line,''}} ->
+ Parent ! {io_request,From,To,{get_line,''}},
+ From ! {io_reply, To, {ok, "hej\n"}},
+ mini_server(Parent)
+ end.
+
+standard_io(suite) ->
+ [];
+standard_io(doc) ->
+ ["Test that standard i/o-servers work with file module"];
+standard_io(Config) when is_list(Config) ->
+ %% Really just a smoke test
+ ?line Pid = spawn(?MODULE,mini_server,[self()]),
+ ?line register(mini_server,Pid),
+ ?line ok = file:write(mini_server,<<"hej\n">>),
+ ?line receive
+ {io_request,_,_,{put_chars,<<"hej\n">>}} ->
+ ok
+ after 1000 ->
+ exit(noreply)
+ end,
+ ?line {ok,"aaaaa"} = file:read(mini_server,5),
+ ?line receive
+ {io_request,_,_,{get_chars,'',5}} ->
+ ok
+ after 1000 ->
+ exit(noreply)
+ end,
+ ?line {ok,"hej\n"} = file:read_line(mini_server),
+ ?line receive
+ {io_request,_,_,{get_line,''}} ->
+ ok
+ after 1000 ->
+ exit(noreply)
+ end,
+ ?line OldGL = group_leader(),
+ ?line group_leader(Pid,self()),
+ ?line ok = file:write(standard_io,<<"hej\n">>),
+ ?line group_leader(OldGL,self()),
+ ?line receive
+ {io_request,_,_,{put_chars,<<"hej\n">>}} ->
+ ok
+ after 1000 ->
+ exit(noreply)
+ end,
+ ?line group_leader(Pid,self()),
+ ?line {ok,"aaaaa"} = file:read(standard_io,5),
+ ?line group_leader(OldGL,self()),
+ ?line receive
+ {io_request,_,_,{get_chars,'',5}} ->
+ ok
+ after 1000 ->
+ exit(noreply)
+ end,
+ ?line group_leader(Pid,self()),
+ ?line {ok,"hej\n"} = file:read_line(standard_io),
+ ?line group_leader(OldGL,self()),
+ ?line receive
+ {io_request,_,_,{get_line,''}} ->
+ ok
+ after 1000 ->
+ exit(noreply)
+ end,
+ Pid ! die,
+ receive after 1000 -> ok end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
read_write_file(suite) -> [];
read_write_file(doc) -> [];
@@ -377,7 +461,9 @@ win_cur_dir_1(_Config) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-files(suite) -> [open,pos,file_info,consult,eval,script,truncate,sync].
+files(suite) ->
+ [open,pos,file_info,consult,eval,script,truncate,
+ sync,datasync,advise].
open(suite) -> [open1,old_modes,new_modes,path_open,close,access,read_write,
pread_write,append,open_errors].
@@ -1355,6 +1441,30 @@ truncate(Config) when is_list(Config) ->
ok.
+datasync(suite) -> [];
+datasync(doc) -> "Tests that ?FILE_MODULE:datasync/1 at least doesn't crash.";
+datasync(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Sync = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_sync.fil"),
+
+ %% Raw open.
+ ?line {ok, Fd} = ?FILE_MODULE:open(Sync, [write, raw]),
+ ?line ok = ?FILE_MODULE:datasync(Fd),
+ ?line ok = ?FILE_MODULE:close(Fd),
+
+ %% Ordinary open.
+ ?line {ok, Fd2} = ?FILE_MODULE:open(Sync, [write]),
+ ?line ok = ?FILE_MODULE:datasync(Fd2),
+ ?line ok = ?FILE_MODULE:close(Fd2),
+
+ ?line [] = flush(),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+
sync(suite) -> [];
sync(doc) -> "Tests that ?FILE_MODULE:sync/1 at least doesn't crash.";
sync(Config) when is_list(Config) ->
@@ -1378,6 +1488,77 @@ sync(Config) when is_list(Config) ->
?line test_server:timetrap_cancel(Dog),
ok.
+advise(suite) -> [];
+advise(doc) -> "Tests that ?FILE_MODULE:advise/4 at least doesn't crash.";
+advise(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Advise = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_advise.fil"),
+
+ Line1 = "Hello\n",
+ Line2 = "World!\n",
+
+ ?line {ok, Fd} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd, 0, 0, normal),
+ ?line ok = io:format(Fd, "~s", [Line1]),
+ ?line ok = io:format(Fd, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd),
+
+ ?line {ok, Fd2} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd2, 0, 0, random),
+ ?line ok = io:format(Fd2, "~s", [Line1]),
+ ?line ok = io:format(Fd2, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd2),
+
+ ?line {ok, Fd3} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd3, 0, 0, sequential),
+ ?line ok = io:format(Fd3, "~s", [Line1]),
+ ?line ok = io:format(Fd3, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd3),
+
+ ?line {ok, Fd4} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd4, 0, 0, will_need),
+ ?line ok = io:format(Fd4, "~s", [Line1]),
+ ?line ok = io:format(Fd4, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd4),
+
+ ?line {ok, Fd5} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd5, 0, 0, dont_need),
+ ?line ok = io:format(Fd5, "~s", [Line1]),
+ ?line ok = io:format(Fd5, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd5),
+
+ ?line {ok, Fd6} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = ?FILE_MODULE:advise(Fd6, 0, 0, no_reuse),
+ ?line ok = io:format(Fd6, "~s", [Line1]),
+ ?line ok = io:format(Fd6, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd6),
+
+ ?line {ok, Fd7} = ?FILE_MODULE:open(Advise, [write]),
+ ?line {error, einval} = ?FILE_MODULE:advise(Fd7, 0, 0, bad_advise),
+ ?line ok = ?FILE_MODULE:close(Fd7),
+
+ %% test write without advise, then a read after an advise
+ ?line {ok, Fd8} = ?FILE_MODULE:open(Advise, [write]),
+ ?line ok = io:format(Fd8, "~s", [Line1]),
+ ?line ok = io:format(Fd8, "~s", [Line2]),
+ ?line ok = ?FILE_MODULE:close(Fd8),
+ ?line {ok, Fd9} = ?FILE_MODULE:open(Advise, [read]),
+ Offset = 0,
+ %% same as a 0 length in some implementations
+ Length = length(Line1) + length(Line2),
+ ?line ok = ?FILE_MODULE:advise(Fd9, Offset, Length, sequential),
+ ?line {ok, Line1} = ?FILE_MODULE:read_line(Fd9),
+ ?line {ok, Line2} = ?FILE_MODULE:read_line(Fd9),
+ ?line eof = ?FILE_MODULE:read_line(Fd9),
+ ?line ok = ?FILE_MODULE:close(Fd9),
+
+ ?line [] = flush(),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/lib/kernel/test/os_SUITE.erl b/lib/kernel/test/os_SUITE.erl
index 6a3534b094..ace9501d18 100644
--- a/lib/kernel/test/os_SUITE.erl
+++ b/lib/kernel/test/os_SUITE.erl
@@ -137,6 +137,13 @@ find_executable(Config) when is_list(Config) ->
?line find_exe(Abin, "my_ar", ".exe", Path),
?line find_exe(Abin, "my_ascii", ".com", Path),
?line find_exe(Abin, "my_adb", ".bat", Path),
+ %% OTP-3626 find names of executables given with extension
+ ?line find_exe(Abin, "my_ar.exe", "", Path),
+ ?line find_exe(Abin, "my_ascii.com", "", Path),
+ ?line find_exe(Abin, "my_adb.bat", "", Path),
+ ?line find_exe(Abin, "my_ar.EXE", "", Path),
+ ?line find_exe(Abin, "my_ascii.COM", "", Path),
+ ?line find_exe(Abin, "MY_ADB.BAT", "", Path),
%% Search for programs in Abin (second element in PATH).
?line find_exe(Abin, "my_ar", ".exe", Path),
diff --git a/lib/kernel/test/pg2_SUITE.erl b/lib/kernel/test/pg2_SUITE.erl
index 8eb1a7ca19..df28dcf447 100644
--- a/lib/kernel/test/pg2_SUITE.erl
+++ b/lib/kernel/test/pg2_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%
%%----------------------------------------------------------------
%% Purpose:Test Suite for the 'pg2' module.
@@ -26,8 +26,8 @@
-export([all/1, init_per_testcase/2, fin_per_testcase/2]).
--export([tickets/1,
- otp_7277/1, otp_8259/1,
+-export([tickets/1,
+ otp_7277/1, otp_8259/1, otp_8653/1,
compat/1, basic/1]).
% Default timetrap timeout (set in init_per_testcase).
@@ -37,7 +37,8 @@
-define(testcase, ?config(?TESTCASE, Config)).
%% Internal export.
--export([mk_part_node/3, part1/5, p_init/3, start_proc/1, sane/0]).
+-export([mk_part_node_and_group/3, part2/4,
+ mk_part_node/3, part1/5, p_init/3, start_proc/1, sane/0]).
init_per_testcase(Case, Config) ->
?line Dog = ?t:timetrap(?default_timeout),
@@ -48,11 +49,11 @@ fin_per_testcase(_Case, _Config) ->
test_server:timetrap_cancel(Dog),
ok.
-all(suite) ->
+all(suite) ->
[tickets].
tickets(suite) ->
- [otp_7277, otp_8259, compat, basic].
+ [otp_7277, otp_8259, otp_8653, compat, basic].
otp_7277(doc) ->
"OTP-7277. Bugfix leave().";
@@ -65,9 +66,9 @@ otp_7277(Config) when is_list(Config) ->
?line ok = pg2:leave(b, P),
?line true = exit(P, kill),
case {pg2:get_members(a), pg2:get_local_members(a)} of
- {[], []} ->
+ {[], []} ->
ok;
- _ ->
+ _ ->
timer:sleep(100),
?line [] = pg2:get_members(a),
?line [] = pg2:get_local_members(a)
@@ -79,6 +80,63 @@ otp_7277(Config) when is_list(Config) ->
-define(UNTIL(Seq), loop_until_true(fun() -> Seq end, Config)).
-define(UNTIL_LOOP, 300).
+otp_8653(suite) -> [];
+otp_8653(doc) ->
+ ["OTP-8259. Member was not removed after being killed."];
+otp_8653(Config) when is_list(Config) ->
+ Timeout = 15,
+ ?line Dog = test_server:timetrap({seconds,Timeout}),
+
+ ?line [A, B, C] = start_nodes([a, b, c], peer, Config),
+
+ ?line wait_for_ready_net(Config),
+
+ % make b and c connected, partitioned from node() and a
+ ?line rpc_cast(B, ?MODULE, part2, [Config, node(), A, C]),
+ ?line ?UNTIL(is_ready_partition(Config)),
+
+ % Connect to the other partition.
+ ?line pong = net_adm:ping(B),
+ timer:sleep(100),
+ ?line pong = net_adm:ping(C),
+ ?line _ = global:sync(),
+ ?line [A, B, C] = lists:sort(nodes()),
+
+ G = pg2_otp_8653,
+ ?line ?UNTIL(begin
+ GA = lists:sort(rpc:call(A, pg2, get_members, [G])),
+ GB = lists:sort(rpc:call(B, pg2, get_members, [G])),
+ GC = lists:sort(rpc:call(C, pg2, get_members, [G])),
+ GT = lists:sort(pg2:get_members(G)),
+ GA =:= GB andalso
+ GB =:= GC andalso
+ GC =:= GT andalso
+ 8 =:= length(GA)
+ end),
+ ?line ok = pg2:delete(G),
+ ?line stop_nodes([A,B,C]),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+part2(Config, Main, A, C) ->
+ Function = mk_part_node_and_group,
+ case catch begin
+ make_partition(Config, [Main, A], [node(), C], Function)
+ end
+ of
+ ok -> ok
+ end.
+
+mk_part_node_and_group(File, MyPart0, Config) ->
+ touch(File, "start"), % debug
+ MyPart = lists:sort(MyPart0),
+ ?UNTIL(is_node_in_part(File, MyPart)),
+ G = pg2_otp_8653,
+ Pid = spawn(forever()),
+ ok = pg2:create(G),
+ _ = [ok = pg2:join(G, Pid) || _ <- [1,1]],
+ touch(File, "done").
+
otp_8259(suite) -> [];
otp_8259(doc) ->
["OTP-8259. Member was not removed after being killed."];
@@ -102,7 +160,7 @@ otp_8259(Config) when is_list(Config) ->
% make b and c connected, partitioned from node() and a
?line rpc_cast(B, ?MODULE, part1, [Config, node(), A, C, Name]),
?line ?UNTIL(is_ready_partition(Config)),
-
+
% Connect to the other partition.
% The resolver on node b will be called.
?line pong = net_adm:ping(B),
@@ -140,9 +198,9 @@ start_proc(Name) ->
p_init(Parent, Name, TestServer) ->
Resolve = fun(_Name, Pid1, Pid2) ->
%% The pid on node a will be chosen.
- [{_,Min}, {_,Max}] =
+ [{_,Min}, {_,Max}] =
lists:sort([{node(Pid1),Pid1}, {node(Pid2),Pid2}]),
- %% b is connected to test_server.
+ %% b is connected to test_server.
%% exit(Min, kill), % would ping a
rpc:cast(TestServer, erlang, exit, [Min, kill]),
Max
@@ -165,7 +223,7 @@ compat(Config) when is_list(Config) ->
true ->
Timeout = 15,
?line Dog = test_server:timetrap({seconds,Timeout}),
- Pid = spawn(forever()),
+ Pid = spawn(forever()),
G = a,
?line ok = pg2:create(G),
?line ok = pg2:join(G, Pid),
@@ -365,7 +423,7 @@ killit(N, P, Ps, Ns) ->
timer:sleep(100),
sane(Ns),
lists:keydelete(P, 1, Ps).
-
+
pr(Node, C) ->
_ = [?t:format("~p: ", [Node]) || Node =/= node()],
?t:format("do ~p~n", [C]).
@@ -412,27 +470,27 @@ sane(Ns) ->
wsane(Ns) ->
%% Same members on all nodes:
- {[_],gs} =
+ {[_],gs} =
{lists:usort([rpc:call(N, pg2, which_groups, []) || N <- Ns]),gs},
- _ = [{[_],ms,G} = {lists:usort([rpc:call(N, pg2, get_members, [G]) ||
+ _ = [{[_],ms,G} = {lists:usort([rpc:call(N, pg2, get_members, [G]) ||
N <- Ns]),ms,G} ||
G <- pg2:which_groups()],
%% The local members are a partitioning of the members:
- [begin
- LocalMembers =
+ [begin
+ LocalMembers =
lists:sort(lists:append(
- [rpc:call(N, pg2, get_local_members, [G]) ||
+ [rpc:call(N, pg2, get_local_members, [G]) ||
N <- Ns])),
{part, LocalMembers} = {part, lists:sort(pg2:get_members(G))}
end || G <- pg2:which_groups()],
%% The closest pid should run on the local node, if possible.
[[case rpc:call(N, pg2, get_closest_pid, [G]) of
Pid when is_pid(Pid), node(Pid) =:= N ->
- true =
+ true =
lists:member(Pid, rpc:call(N, pg2, get_local_members, [G]));
%% FIXME. Om annan nod: member, local = [].
_ -> [] = rpc:call(N, pg2, get_local_members, [G])
- end || N <- Ns]
+ end || N <- Ns]
|| G <- pg2:which_groups()].
%% Look inside the pg2_table.
@@ -482,9 +540,9 @@ start_node_rel(Name, Rel, How) ->
{RelList, ""}
end,
?line Pa = filename:dirname(code:which(?MODULE)),
- ?line Res = test_server:start_node(Name, How,
+ ?line Res = test_server:start_node(Name, How,
[{args,
- Compat ++
+ Compat ++
" -kernel net_setuptime 100 "
" -pa " ++ Pa},
{erl, Release}]),
@@ -575,29 +633,30 @@ get_known(Node) ->
case catch gen_server:call({global_name_server,Node},get_known,infinity) of
{'EXIT', _} ->
[list, without, nodenames];
- Known when is_list(Known) ->
+ Known when is_list(Known) ->
lists:sort([Node | Known])
end.
node_name(Name, Config) ->
U = "_",
{{Y,M,D}, {H,Min,S}} = calendar:now_to_local_time(now()),
- Date = io_lib:format("~4w_~2..0w_~2..0w__~2..0w_~2..0w_~2..0w",
+ Date = io_lib:format("~4w_~2..0w_~2..0w__~2..0w_~2..0w_~2..0w",
[Y,M,D, H,Min,S]),
L = lists:flatten(Date),
lists:concat([Name,U,?testcase,U,U,L]).
-%% this one runs on one node in Part2
-%% The partition is ready when is_ready_partition(Config) returns (true).
-%% this one runs on one node in Part2
+%% This one runs on one node in Part2.
%% The partition is ready when is_ready_partition(Config) returns (true).
make_partition(Config, Part1, Part2) ->
+ make_partition(Config, Part1, Part2, mk_part_node).
+
+make_partition(Config, Part1, Part2, Function) ->
Dir = ?config(priv_dir, Config),
- Ns = [begin
+ Ns = [begin
Name = lists:concat([atom_to_list(N),"_",msec(),".part"]),
File = filename:join([Dir, Name]),
file:delete(File),
- rpc_cast(N, ?MODULE, mk_part_node, [File, Part, Config], File),
+ rpc_cast(N, ?MODULE, Function, [File, Part, Config], File),
{N, File}
end || Part <- [Part1, Part2], N <- Part],
all_nodes_files(Ns, "done", Config),
@@ -614,10 +673,10 @@ mk_part_node(File, MyPart0, Config) ->
%% The calls to append_to_file are for debugging.
is_node_in_part(File, MyPart) ->
- lists:foreach(fun(N) ->
+ lists:foreach(fun(N) ->
_ = erlang:disconnect_node(N)
end, nodes() -- MyPart),
- case {(Known = get_known(node())) =:= MyPart,
+ case {(Known = get_known(node())) =:= MyPart,
(Nodes = lists:sort([node() | nodes()])) =:= MyPart} of
{true, true} ->
%% Make sure the resolvers have been terminated,
@@ -649,7 +708,7 @@ wait_for_ready_net(Nodes0, Config) ->
?t:format("wait_for_ready_net ~p~n", [Nodes]),
?UNTIL(begin
lists:all(fun(N) -> Nodes =:= get_known(N) end, Nodes) and
- lists:all(fun(N) ->
+ lists:all(fun(N) ->
LNs = rpc:call(N, erlang, nodes, []),
Nodes =:= lists:sort([N | LNs])
end, Nodes)
@@ -688,11 +747,11 @@ file_contents(File, ContentsList, Config) ->
file_contents(File, ContentsList, Config, no_log_file).
file_contents(File, ContentsList, Config, LogFile) ->
- Contents = list_to_binary(ContentsList),
+ Contents = list_to_binary(ContentsList),
Sz = size(Contents),
?UNTIL(begin
case file:read_file(File) of
- {ok, FileContents}=Reply ->
+ {ok, FileContents}=Reply ->
case catch split_binary(FileContents, Sz) of
{Contents,_} ->
true;
diff --git a/lib/kernel/test/prim_file_SUITE.erl b/lib/kernel/test/prim_file_SUITE.erl
index 6badbb5090..21bdc06fdc 100644
--- a/lib/kernel/test/prim_file_SUITE.erl
+++ b/lib/kernel/test/prim_file_SUITE.erl
@@ -34,7 +34,7 @@
file_info_times_a/1, file_info_times_b/1,
file_write_file_info_a/1, file_write_file_info_b/1]).
-export([rename_a/1, rename_b/1,
- access/1, truncate/1, sync/1,
+ access/1, truncate/1, datasync/1, sync/1,
read_write/1, pread_write/1, append/1]).
-export([errors/1, e_delete/1, e_rename/1, e_make_dir/1, e_del_dir/1]).
@@ -48,6 +48,8 @@
symlinks_a/1, symlinks_b/1,
list_dir_limit/1]).
+-export([advise/1]).
+
-include("test_server.hrl").
-include_lib("kernel/include/file.hrl").
@@ -380,7 +382,7 @@ win_cur_dir_1(_Config, Handle) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-files(suite) -> [open,pos,file_info,truncate,sync].
+files(suite) -> [open,pos,file_info,truncate,sync,datasync,advise].
open(suite) -> [open1,modes,close,access,read_write,
pread_write,append].
@@ -1064,6 +1066,24 @@ truncate(Config) when is_list(Config) ->
ok.
+datasync(suite) -> [];
+datasync(doc) -> "Tests that ?PRIM_FILE:datasync/1 at least doesn't crash.";
+datasync(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Sync = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_sync.fil"),
+
+ %% Raw open.
+ ?line {ok, Fd} = ?PRIM_FILE:open(Sync, [write]),
+ ?line ok = ?PRIM_FILE:datasync(Fd),
+ ?line ok = ?PRIM_FILE:close(Fd),
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+
sync(suite) -> [];
sync(doc) -> "Tests that ?PRIM_FILE:sync/1 at least doesn't crash.";
sync(Config) when is_list(Config) ->
@@ -1082,6 +1102,77 @@ sync(Config) when is_list(Config) ->
ok.
+advise(suite) -> [];
+advise(doc) -> "Tests that ?PRIM_FILE:advise/4 at least doesn't crash.";
+advise(Config) when is_list(Config) ->
+ ?line Dog = test_server:timetrap(test_server:seconds(5)),
+ ?line PrivDir = ?config(priv_dir, Config),
+ ?line Advise = filename:join(PrivDir,
+ atom_to_list(?MODULE)
+ ++"_advise.fil"),
+
+ Line1 = "Hello\n",
+ Line2 = "World!\n",
+
+ ?line {ok, Fd} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd, 0, 0, normal),
+ ?line ok = ?PRIM_FILE:write(Fd, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd),
+
+ ?line {ok, Fd2} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd2, 0, 0, random),
+ ?line ok = ?PRIM_FILE:write(Fd2, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd2, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd2),
+
+ ?line {ok, Fd3} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd3, 0, 0, sequential),
+ ?line ok = ?PRIM_FILE:write(Fd3, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd3, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd3),
+
+ ?line {ok, Fd4} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd4, 0, 0, will_need),
+ ?line ok = ?PRIM_FILE:write(Fd4, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd4, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd4),
+
+ ?line {ok, Fd5} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd5, 0, 0, dont_need),
+ ?line ok = ?PRIM_FILE:write(Fd5, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd5, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd5),
+
+ ?line {ok, Fd6} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:advise(Fd6, 0, 0, no_reuse),
+ ?line ok = ?PRIM_FILE:write(Fd6, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd6, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd6),
+
+ ?line {ok, Fd7} = ?PRIM_FILE:open(Advise, [write]),
+ ?line {error, einval} = ?PRIM_FILE:advise(Fd7, 0, 0, bad_advise),
+ ?line ok = ?PRIM_FILE:close(Fd7),
+
+ %% test write without advise, then a read after an advise
+ ?line {ok, Fd8} = ?PRIM_FILE:open(Advise, [write]),
+ ?line ok = ?PRIM_FILE:write(Fd8, Line1),
+ ?line ok = ?PRIM_FILE:write(Fd8, Line2),
+ ?line ok = ?PRIM_FILE:close(Fd8),
+ ?line {ok, Fd9} = ?PRIM_FILE:open(Advise, [read]),
+ Offset = 0,
+ %% same as a 0 length in some implementations
+ Length = length(Line1) + length(Line2),
+ ?line ok = ?PRIM_FILE:advise(Fd9, Offset, Length, sequential),
+ ?line {ok, Line1} = ?PRIM_FILE:read_line(Fd9),
+ ?line {ok, Line2} = ?PRIM_FILE:read_line(Fd9),
+ ?line eof = ?PRIM_FILE:read_line(Fd9),
+ ?line ok = ?PRIM_FILE:close(Fd9),
+
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
delete_a(suite) -> [];
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/notes.xml b/lib/megaco/doc/src/notes.xml
index 6e1356b55d..99a3784402 100644
--- a/lib/megaco/doc/src/notes.xml
+++ b/lib/megaco/doc/src/notes.xml
@@ -60,28 +60,37 @@
<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>
+ <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>
diff --git a/lib/megaco/src/app/megaco.appup.src b/lib/megaco/src/app/megaco.appup.src
index 5df31f2923..f939f5e6cf 100644
--- a/lib/megaco/src/app/megaco.appup.src
+++ b/lib/megaco/src/app/megaco.appup.src
@@ -133,13 +133,16 @@
[
{"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, []},
+ {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, []}
@@ -173,13 +176,16 @@
[
{"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, []},
+ {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, []}
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 0445f10838..6805db790d 100644
--- a/lib/megaco/src/engine/megaco_config.erl
+++ b/lib/megaco/src/engine/megaco_config.erl
@@ -628,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
@@ -660,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
@@ -671,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
diff --git a/lib/megaco/src/engine/megaco_messenger.erl b/lib/megaco/src/engine/megaco_messenger.erl
index 5756e8e896..5fad29931b 100644
--- a/lib/megaco/src/engine/megaco_messenger.erl
+++ b/lib/megaco/src/engine/megaco_messenger.erl
@@ -1541,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;
@@ -1572,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
@@ -2648,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;
+
+ {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;
- [#request{user_mod = UserMod,
- user_args = UserArgs,
- reply_action = Action,
- reply_data = UserData,
- remote_mid = RMid}] ->
+ {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),
@@ -2685,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)
@@ -2716,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
@@ -3739,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,
@@ -4323,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},
@@ -4380,29 +4405,67 @@ 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.
+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) ->
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 6ce9b34617..5af651d89b 100644
--- a/lib/megaco/src/flex/Makefile.in
+++ b/lib/megaco/src/flex/Makefile.in
@@ -280,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
diff --git a/lib/megaco/vsn.mk b/lib/megaco/vsn.mk
index 34a5ac1ed2..4ef0ed8f18 100644
--- a/lib/megaco/vsn.mk
+++ b/lib/megaco/vsn.mk
@@ -22,7 +22,7 @@ MEGACO_VSN = 3.14.1
PRE_VSN =
APP_VSN = "$(APPLICATION)-$(MEGACO_VSN)$(PRE_VSN)"
-TICKETS = OTP-8561
+TICKETS = OTP-8529 OTP-8561 OTP-8627 OTP-8634
TICKETS_3_14 = OTP-8317 OTP-8323 OTP-8328 OTP-8362 OTP-8403
diff --git a/lib/mnesia/src/mnesia_controller.erl b/lib/mnesia/src/mnesia_controller.erl
index 14e28bdc14..0298b382a6 100644
--- a/lib/mnesia/src/mnesia_controller.erl
+++ b/lib/mnesia/src/mnesia_controller.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%
%%
@@ -52,6 +52,7 @@
async_dump_log/1,
sync_dump_log/1,
connect_nodes/1,
+ connect_nodes/2,
wait_for_schema_commit_lock/0,
release_schema_commit_lock/0,
create_table/1,
@@ -94,7 +95,7 @@
load_and_reply/2,
send_and_reply/2,
wait_for_tables_init/2,
- connect_nodes2/2
+ connect_nodes2/3
]).
-import(mnesia_lib, [set/2, add/2]).
@@ -420,12 +421,15 @@ try_schedule_late_disc_load(Tabs, Reason, MsgTag) ->
[[Tabs, Reason, MsgTag], AbortReason])
end.
-connect_nodes(Ns) ->
+connect_nodes(Ns) ->
+ connect_nodes(Ns, fun default_merge/1).
+
+connect_nodes(Ns, UserFun) ->
case mnesia:system_info(is_running) of
no ->
{error, {node_not_running, node()}};
yes ->
- Pid = spawn_link(?MODULE,connect_nodes2,[self(),Ns]),
+ Pid = spawn_link(?MODULE,connect_nodes2,[self(),Ns, UserFun]),
receive
{?MODULE, Pid, Res, New} ->
case Res of
@@ -443,7 +447,7 @@ connect_nodes(Ns) ->
end
end.
-connect_nodes2(Father, Ns) ->
+connect_nodes2(Father, Ns, UserFun) ->
Current = val({current, db_nodes}),
abcast([node()|Ns], {merging_schema, node()}),
{NewC, OldC} = mnesia_recover:connect_nodes(Ns),
@@ -451,7 +455,7 @@ connect_nodes2(Father, Ns) ->
New1 = mnesia_lib:intersect(Ns, Connected),
New = New1 -- Current,
process_flag(trap_exit, true),
- Res = try_merge_schema(New),
+ Res = try_merge_schema(New, UserFun),
Msg = {schema_is_merged, [], late_merge, []},
multicall([node()|Ns], Msg),
After = val({current, db_nodes}),
@@ -465,7 +469,7 @@ connect_nodes2(Father, Ns) ->
merge_schema() ->
AllNodes = mnesia_lib:all_nodes(),
- case try_merge_schema(AllNodes) of
+ case try_merge_schema(AllNodes, fun default_merge/1) of
ok ->
schema_is_merged();
{aborted, {throw, Str}} when is_list(Str) ->
@@ -474,8 +478,11 @@ merge_schema() ->
fatal("Failed to merge schema: ~p~n", [Else])
end.
-try_merge_schema(Nodes) ->
- case mnesia_schema:merge_schema() of
+default_merge(F) ->
+ F([]).
+
+try_merge_schema(Nodes, UserFun) ->
+ case mnesia_schema:merge_schema(UserFun) of
{atomic, not_merged} ->
%% No more nodes that we need to merge the schema with
ok;
@@ -488,11 +495,11 @@ try_merge_schema(Nodes) ->
im_running(OldFriends, NewFriends),
im_running(NewFriends, OldFriends),
- try_merge_schema(Nodes);
+ try_merge_schema(Nodes, UserFun);
{atomic, {"Cannot get cstructs", Node, Reason}} ->
dbg_out("Cannot get cstructs, Node ~p ~p~n", [Node, Reason]),
timer:sleep(1000), % Avoid a endless loop look alike
- try_merge_schema(Nodes);
+ try_merge_schema(Nodes, UserFun);
Other ->
Other
end.
diff --git a/lib/mnesia/src/mnesia_lib.erl b/lib/mnesia/src/mnesia_lib.erl
index 168e225289..3da3dd2f5c 100644
--- a/lib/mnesia/src/mnesia_lib.erl
+++ b/lib/mnesia/src/mnesia_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%
%%
diff --git a/lib/mnesia/src/mnesia_recover.erl b/lib/mnesia/src/mnesia_recover.erl
index 051b193da7..0ca7bf3f7f 100644
--- a/lib/mnesia/src/mnesia_recover.erl
+++ b/lib/mnesia/src/mnesia_recover.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%
%%
diff --git a/lib/mnesia/src/mnesia_schema.erl b/lib/mnesia/src/mnesia_schema.erl
index 354431a296..17e570b881 100644
--- a/lib/mnesia/src/mnesia_schema.erl
+++ b/lib/mnesia/src/mnesia_schema.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%
%%
@@ -62,6 +62,7 @@
list2cs/1,
lock_schema/0,
merge_schema/0,
+ merge_schema/1,
move_table/3,
opt_create_dir/2,
prepare_commit/3,
@@ -2650,10 +2651,16 @@ make_dump_tables([]) ->
%% Merge the local schema with the schema on other nodes
merge_schema() ->
- schema_transaction(fun() -> do_merge_schema() end).
+ schema_transaction(fun() -> do_merge_schema([]) end).
+
+merge_schema(UserFun) ->
+ schema_transaction(fun() -> UserFun(fun(Arg) -> do_merge_schema(Arg) end) end).
-do_merge_schema() ->
+
+do_merge_schema(LockTabs0) ->
{_Mod, Tid, Ts} = get_tid_ts_and_lock(schema, write),
+ LockTabs = [{T, tab_to_nodes(T)} || T <- LockTabs0],
+ [get_tid_ts_and_lock(T,write) || {T,_} <- LockTabs],
Connected = val(recover_nodes),
Running = val({current, db_nodes}),
Store = Ts#tidstore.store,
@@ -2665,9 +2672,12 @@ do_merge_schema() ->
mnesia:abort({bad_commit, {missing_lock, Miss}})
end,
case Connected -- Running of
- [Node | _] ->
+ [Node | _] = OtherNodes ->
%% Time for a schema merging party!
mnesia_locker:wlock_no_exist(Tid, Store, schema, [Node]),
+ [mnesia_locker:wlock_no_exist(
+ Tid, Store, T, mnesia_lib:intersect(Ns, OtherNodes))
+ || {T,Ns} <- LockTabs],
case rpc:call(Node, mnesia_controller, get_cstructs, []) of
{cstructs, Cstructs, RemoteRunning1} ->
LockedAlready = Running ++ [Node],
@@ -2681,6 +2691,9 @@ do_merge_schema() ->
end,
NeedsLock = RemoteRunning -- LockedAlready,
mnesia_locker:wlock_no_exist(Tid, Store, schema, NeedsLock),
+ [mnesia_locker:wlock_no_exist(Tid, Store, T,
+ mnesia_lib:intersect(Ns,NeedsLock))
+ || {T,Ns} <- LockTabs],
{value, SchemaCs} =
lists:keysearch(schema, #cstruct.name, Cstructs),
@@ -2714,6 +2727,10 @@ do_merge_schema() ->
not_merged
end.
+tab_to_nodes(Tab) when is_atom(Tab) ->
+ Cs = val({Tab, cstruct}),
+ mnesia_lib:cs_to_nodes(Cs).
+
make_merge_schema(Node, [Cs | Cstructs]) ->
Ops = do_make_merge_schema(Node, Cs),
Ops ++ make_merge_schema(Node, Cstructs);
diff --git a/lib/odbc/test/Makefile b/lib/odbc/test/Makefile
new file mode 100644
index 0000000000..935ecbf5a7
--- /dev/null
+++ b/lib/odbc/test/Makefile
@@ -0,0 +1,114 @@
+#
+# %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
+
+
+INCLUDES= -I. -I$(ERL_TOP)/lib/test_server/include/ -I$(ERL_TOP)/lib/odbc/src
+
+# ----------------------------------------------------
+# Target Specs
+# ----------------------------------------------------
+
+MODULES= \
+ odbc_start_SUITE \
+ odbc_connect_SUITE \
+ odbc_query_SUITE \
+ odbc_data_type_SUITE \
+ odbc_test_lib \
+ oracle \
+ sqlserver \
+ postgres
+
+EBIN = .
+
+ERL_FILES= $(MODULES:%=%.erl)
+
+HRL_FILES= odbc_test.hrl\
+
+TARGET_FILES= \
+ $(MODULES:%=$(EBIN)/%.$(EMULATOR))
+
+SPEC_FILES = odbc.spec odbc.dynspec \
+ odbc.spec.win
+
+EMAKEFILE = Emakefile
+MAKE_EMAKE = $(wildcard $(ERL_TOP)/make/make_emakefile)
+
+ifeq ($(MAKE_EMAKE),)
+BUILDTARGET = $(TARGET_FILES)
+RELTEST_FILES = $(SPEC_FILES) $(SOURCE)
+else
+BUILDTARGET = emakebuild
+RELTEST_FILES = $(EMAKEFILE) $(SPEC_FILES) $(SOURCE)
+endif
+
+# ----------------------------------------------------
+# Release directory specification
+# ----------------------------------------------------
+RELSYSDIR = $(RELEASE_PATH)/odbc_test
+
+# ----------------------------------------------------
+# FLAGS
+# ----------------------------------------------------
+
+ERL_COMPILE_FLAGS += $(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 $(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) $(SPEC_FILES) $(ERL_FILES) $(HRL_FILES) $(RELSYSDIR)
+
+
+release_docs_spec:
+
+
+
+
+
+
+
diff --git a/lib/odbc/test/README b/lib/odbc/test/README
new file mode 100644
index 0000000000..1f3c659e28
--- /dev/null
+++ b/lib/odbc/test/README
@@ -0,0 +1,86 @@
+-------------------------------------------------------------------------
+ TEST SUITE REQUIREMENTS
+-------------------------------------------------------------------------
+As third party products are involved when using ODBC you will have to
+setup your own test environment to be able to run the ODBC test
+suites.
+
+You need to install a database such as postgres, sql-server, oracle
+etc, and ODBC-drivers for that database.
+
+Then you need to setup a test database, however you do not
+need to create any tables that will be done by the test suites.
+The test suites will also remove all tables that it creates when
+the test is complete.
+
+-------------------------------------------------------------------------
+ERLANG FILES YOU MAY NEED TO CHANGE
+-------------------------------------------------------------------------
+
+A remote database management system has a callback module to handle
+possible differences in data type handling etc, the callback module
+also defines the ODBC connection string. Currently available callback
+modules are postgres.erl, sqlserver.erl and oracle.erl. Depending on
+how you set things up you might want to edit the connection string in
+the callback module or even add your own callback module.
+
+The callback module used in each test case is defined by the ?RDBMS
+macro defined in odbc_test.hrl so you might need to change this to
+suite your purposes.
+
+-------------------------------------------------------------------------
+EXAMPLE
+-------------------------------------------------------------------------
+
+As an example say we have the database odbctestdb, with
+the user odbctest that has the password Sesame. The database
+runs on the host myhost.
+
+UINX/LINUX
+-----------
+
+Set up a database and install the unixODBC drivers.
+Then the unix/linux user that should run the test suits needs an .odbc.ini
+file to map connection data. For example ODBC connection string:
+"DSN=Postgres;UID=odbctest" will need an .odbc.ini entry that looks
+something like this:
+
+--- Start example of .odbc.ini ----
+
+[Postgres]
+Driver=/usr/lib/psqlodbc.so
+Description=Postgres driver
+ServerName=myhost
+Database=odbctestdb
+Port=5432
+LogonID=odbctest
+Password=Sesame
+
+---End example of .odbc.ini ------------
+
+
+WINDOWS MOST FLAVORS
+--------------------
+
+There will be a "ODBC data source administrator" tool under
+Control Panel -> Administrative Tools, use this to set up
+your database. Choose to connect with SQL Server authentication.
+As odbc connection string use: "DSN=odbctestdb;UID=odbctest;PWD=Sesame"
+
+
+> %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%
diff --git a/lib/odbc/test/odbc.dynspec b/lib/odbc/test/odbc.dynspec
new file mode 100644
index 0000000000..bb15edceed
--- /dev/null
+++ b/lib/odbc/test/odbc.dynspec
@@ -0,0 +1,31 @@
+%% -*- erlang -*-
+%% You can test this file using this command.
+%% file:script("odbc.dynspec", [{'Os',"Unix"}]).
+
+Exists =
+fun() ->
+ case code:lib_dir(odbc) of
+ {error,bad_name} ->
+ false;
+ P ->
+ %% Make sure that the odbc directory really
+ %% contains the application (and not only documentation).
+ case filelib:is_file(filename:join(P, "ebin/odbc.beam")) of
+ false -> false;
+ true ->
+ %% We know that we don't have any odbc libraries
+ %% installed on this computer.
+ {ok,Host} = inet:gethostname(),
+ Host =/= "netsim200"
+ end
+ end
+end,
+case Exists() of
+ false ->
+ NoOdbc = "No odbc application",
+ [{skip, {odbc_connect_SUITE, NoOdbc}},
+ {skip, {odbc_data_type_SUITE, NoOdbc}},
+ {skip, {odbc_query_SUITE, NoOdbc}}];
+ true ->
+ []
+end.
diff --git a/lib/odbc/test/odbc.spec b/lib/odbc/test/odbc.spec
new file mode 100644
index 0000000000..acba9f8d98
--- /dev/null
+++ b/lib/odbc/test/odbc.spec
@@ -0,0 +1,9 @@
+{topcase, {dir, "../odbc_test"}}.
+{skip, {odbc_data_type_SUITE, varchar_upper_limit, "Known bug in database"}}.
+{skip, {odbc_data_type_SUITE, text_upper_limit, "Consumes too much resources"}}.
+{skip, {odbc_data_type_SUITE, bit_true , "Not supported by driver"}}.
+{skip, {odbc_data_type_SUITE, bit_false, "Not supported by driver"}}.
+{skip, {odbc_query_SUITE, multiple_select_result_sets,"Not supported by driver"}}.
+{skip, {odbc_query_SUITE, multiple_mix_result_sets, "Not supported by driver"}}.
+{skip, {odbc_query_SUITE, multiple_result_sets_error, "Not supported by driver"}}.
+{skip, {odbc_query_SUITE, param_insert_tiny_int, "Not supported by driver"}}. \ No newline at end of file
diff --git a/lib/odbc/test/odbc.spec.win b/lib/odbc/test/odbc.spec.win
new file mode 100644
index 0000000000..1fd349d2c3
--- /dev/null
+++ b/lib/odbc/test/odbc.spec.win
@@ -0,0 +1,5 @@
+{topcase, {dir, "../odbc_test"}}.
+{skip, {odbc_data_type_SUITE, big_int_lower_limit, "Not supported by sqlserver 7.0"}}.
+{skip, {odbc_data_type_SUITE, big_int_upper_limit, "Not supported by sqlserver7.0"}}.
+{skip, {odbc_data_type_SUITE, text_upper_limit, "Consumes too much resources"}}.
+
diff --git a/lib/odbc/test/odbc_connect_SUITE.erl b/lib/odbc/test/odbc_connect_SUITE.erl
new file mode 100644
index 0000000000..4d37a8f543
--- /dev/null
+++ b/lib/odbc/test/odbc_connect_SUITE.erl
@@ -0,0 +1,816 @@
+%%
+%% %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(odbc_connect_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("odbc_test.hrl").
+
+-define(MAX_SEQ_TIMEOUTS, 10).
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ["Tests the ability to connect and disconnet to/from the database"];
+all(suite) ->
+ case odbc_test_lib:odbc_check() of
+ ok -> all();
+ Other -> {skip, Other}
+ end.
+
+all() ->
+ [not_exist_db, commit, rollback, not_explicit_commit,
+ no_c_node, port_dies, control_process_dies, client_dies,
+ connect_timeout, timeout, many_timeouts, timeout_reset,
+ disconnect_on_timeout, connection_closed,
+ disable_scrollable_cursors, return_rows_as_lists, api_missuse].
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ application:start(odbc),
+ case odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]) of
+ {ok, Ref} ->
+ odbc:disconnect(Ref),
+ [{tableName, odbc_test_lib:unique_table_name()} | Config];
+ _ ->
+ {skip, "ODBC is not properly setup"}
+ end.
+%%--------------------------------------------------------------------
+%% Function: end_per_suite(Config) -> _
+%% Config - [tuple()]
+%% A list of key/value pairs, holding the test case configuration.
+%% Description: Cleanup after the whole suite
+%%--------------------------------------------------------------------
+end_per_suite(_Config) ->
+ application:stop(odbc),
+ 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(_TestCase, Config) ->
+ test_server:format("ODBCINI = ~p~n", [os:getenv("ODBCINI")]),
+ Dog = test_server:timetrap(?default_timeout),
+ Temp = lists:keydelete(connection_ref, 1, Config),
+ NewConfig = lists:keydelete(watchdog, 1, Temp),
+ [{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(_TestCase, Config) ->
+ %% Clean up if needed
+ Table = ?config(tableName, Config),
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ Result = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+ io:format("Drop table: ~p ~p~n", [Table, Result]),
+ odbc:disconnect(Ref),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+commit(doc)->
+ ["Test the use of explicit commit"];
+commit(suite) -> [];
+commit(Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+
+ Table = ?config(tableName, Config),
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10))"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1,'bar')"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+
+ ok = odbc:commit(Ref, commit),
+ UpdateResult = ?RDBMS:update_result(),
+ UpdateResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'bar' WHERE ID = 1"),
+ ok = odbc:commit(Ref, commit, ?TIMEOUT),
+ InsertResult = ?RDBMS:insert_result(),
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {'EXIT', {function_clause, _}} =
+ (catch odbc:commit(Ref, commit, -1)),
+
+ ok = odbc:disconnect(Ref),
+
+ ok.
+%%-------------------------------------------------------------------------
+
+rollback(doc)->
+ ["Test the use of explicit rollback"];
+rollback(suite) -> [];
+rollback(Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10))"),
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+ ok = odbc:commit(Ref, commit),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+ ok = odbc:commit(Ref, rollback),
+ InsertResult = ?RDBMS:insert_result(),
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+ ok = odbc:commit(Ref, rollback, ?TIMEOUT),
+ InsertResult = ?RDBMS:insert_result(),
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+
+ {'EXIT', {function_clause, _}} =
+ (catch odbc:commit(Ref, rollback, -1)),
+
+ ok = odbc:disconnect(Ref),
+ ok.
+
+%%-------------------------------------------------------------------------
+not_explicit_commit(doc) ->
+ ["Test what happens if you try using commit on a auto_commit connection."];
+not_explicit_commit(suite) -> [];
+not_explicit_commit(_Config) ->
+ {ok, Ref} =
+ odbc:connect(?RDBMS:connection_string(), [{auto_commit, on}]),
+ {error, _} = odbc:commit(Ref, commit),
+ ok = odbc:disconnect(Ref),
+ ok.
+
+%%-------------------------------------------------------------------------
+not_exist_db(doc) ->
+ ["Tests valid data format but invalid data in the connection parameters."];
+not_exist_db(suite) -> [];
+not_exist_db(_Config) ->
+ {error, _} = odbc:connect("DSN=foo;UID=bar;PWD=foobar", []),
+ %% So that the odbc control server can be stoped "in the correct way"
+ test_server:sleep(100),
+ ok.
+
+%%-------------------------------------------------------------------------
+no_c_node(doc) ->
+ "Test what happens if the port-program can not be found";
+no_c_node(suite) -> [];
+no_c_node(_Config) ->
+ process_flag(trap_exit, true),
+ Dir = filename:nativename(filename:join(code:priv_dir(odbc),
+ "bin")),
+ FileName1 = filename:nativename(os:find_executable("odbcserver",
+ Dir)),
+ FileName2 = filename:nativename(filename:join(Dir, "odbcsrv")),
+ ok = file:rename(FileName1, FileName2),
+ Result =
+ case catch odbc:connect(?RDBMS:connection_string(), []) of
+ {error, port_program_executable_not_found} ->
+ ok;
+ Else ->
+ Else
+ end,
+
+ ok = file:rename(FileName2, FileName1),
+ ok = Result.
+%%------------------------------------------------------------------------
+
+port_dies(doc) ->
+ "Tests what happens if the port program dies";
+port_dies(suite) -> [];
+port_dies(_Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ {status, _} = process_info(Ref, status),
+ process_flag(trap_exit, true),
+ Port = lists:last(erlang:ports()),
+ exit(Port, kill),
+ %% Wait for exit_status from port 5000 ms (will not get a exit
+ %% status in this case), then wait a little longer to make sure
+ %% the port and the controlprocess has had time to terminate.
+ test_server:sleep(7000),
+ undefined = process_info(Ref, status),
+ ok.
+
+%%-------------------------------------------------------------------------
+control_process_dies(doc) ->
+ "Tests what happens if the Erlang control process dies";
+control_process_dies(suite) -> [];
+control_process_dies(_Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ process_flag(trap_exit, true),
+ Port = lists:last(erlang:ports()),
+ {connected, Ref} = erlang:port_info(Port, connected),
+ exit(Ref, kill),
+ test_server:sleep(100),
+ undefined = erlang:port_info(Port, connected),
+ %% Check for c-program still running, how?
+ ok.
+
+%%-------------------------------------------------------------------------
+client_dies(doc) ->
+ ["Test that the odbc process is terminated when the client process "
+ "dies"];
+client_dies(suite) ->
+ [client_dies_normal, client_dies_timeout, client_dies_error].
+
+%%-------------------------------------------------------------------------
+client_dies_normal(doc) ->
+ ["Client dies with reason normal."];
+client_dies_normal(suite) -> [];
+client_dies_normal(Config) when is_list(Config) ->
+ Pid = spawn(?MODULE, client_normal, [self()]),
+
+ MonitorReference =
+ receive
+ {dbRef, Ref} ->
+ MRef = erlang:monitor(process, Ref),
+ Pid ! continue,
+ MRef
+ end,
+
+ receive
+ {'DOWN', MonitorReference, _Type, _Object, _Info} ->
+ ok
+ after 5000 ->
+ test_server:fail(control_process_not_stopped)
+ end.
+
+client_normal(Pid) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ Pid ! {dbRef, Ref},
+ receive
+ continue ->
+ ok
+ end,
+ exit(self(), normal).
+
+
+%%-------------------------------------------------------------------------
+client_dies_timeout(doc) ->
+ ["Client dies with reason timeout."];
+client_dies_timeout(suite) -> [];
+client_dies_timeout(Config) when is_list(Config) ->
+ Pid = spawn(?MODULE, client_timeout, [self()]),
+
+ MonitorReference =
+ receive
+ {dbRef, Ref} ->
+ MRef = erlang:monitor(process, Ref),
+ Pid ! continue,
+ MRef
+ end,
+
+ receive
+ {'DOWN', MonitorReference, _Type, _Object, _Info} ->
+ ok
+ after 5000 ->
+ test_server:fail(control_process_not_stopped)
+ end.
+
+client_timeout(Pid) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ Pid ! {dbRef, Ref},
+ receive
+ continue ->
+ ok
+ end,
+ exit(self(), timeout).
+
+
+%%-------------------------------------------------------------------------
+client_dies_error(doc) ->
+ ["Client dies with reason error."];
+client_dies_error(suite) -> [];
+client_dies_error(Config) when is_list(Config) ->
+ Pid = spawn(?MODULE, client_error, [self()]),
+
+ MonitorReference =
+ receive
+ {dbRef, Ref} ->
+ MRef = erlang:monitor(process, Ref),
+ Pid ! continue,
+ MRef
+ end,
+
+ receive
+ {'DOWN', MonitorReference, _Type, _Object, _Info} ->
+ ok
+ after 5000 ->
+ test_server:fail(control_process_not_stopped)
+ end.
+
+client_error(Pid) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ Pid ! {dbRef, Ref},
+ receive
+ continue ->
+ ok
+ end,
+ exit(self(), error).
+
+
+%%-------------------------------------------------------------------------
+connect_timeout(doc) ->
+ ["Test the timeout for the connect function."];
+connect_timeout(suite) -> [];
+connect_timeout(Config) when is_list(Config) ->
+ {'EXIT',timeout} = (catch odbc:connect(?RDBMS:connection_string(),
+ [{timeout, 0}])),
+ ok.
+%%-------------------------------------------------------------------------
+timeout(doc) ->
+ ["Test that timeouts don't cause unwanted behavior sush as receiving"
+ " an anwser to a previously tiemed out query."];
+timeout(suite) -> [];
+timeout(Config) when is_list(Config) ->
+
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ ok = odbc:commit(Ref, commit),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(2,'baz')"),
+
+ Pid = spawn_link(?MODULE, update_table_timeout, [Table, 5000, self()]),
+
+ receive
+ timout_occurred ->
+ ok = odbc:commit(Ref, commit),
+ Pid ! continue
+ end,
+
+ receive
+ altered ->
+ ok
+ end,
+
+ {selected, Fields, [{"foobar"}]} =
+ odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 1"),
+ ["DATA"] = odbc_test_lib:to_upper(Fields),
+
+ ok = odbc:commit(Ref, commit),
+ ok = odbc:disconnect(Ref),
+ ok.
+
+
+update_table_timeout(Table, TimeOut, Pid) ->
+
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+ UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
+
+ case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
+ {'EXIT', timeout} ->
+ Pid ! timout_occurred;
+ {updated, 1} ->
+ test_server:fail(database_locker_failed)
+ end,
+
+ receive
+ continue ->
+ ok
+ end,
+
+ %% Make sure we receive the correct result and not the answer
+ %% to the previous query.
+ {selected, Fields, [{"baz"}]} =
+ odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 2"),
+ ["DATA"] = odbc_test_lib:to_upper(Fields),
+
+ {updated, 1} = odbc:sql_query(Ref, UpdateQuery, TimeOut),
+
+ ok = odbc:commit(Ref, commit),
+
+ Pid ! altered,
+
+ ok = odbc:disconnect(Ref),
+
+ ok.
+%%-------------------------------------------------------------------------
+many_timeouts(doc) ->
+ ["Tests that many consecutive timeouts lead to that the connection "
+ "is shutdown."];
+many_timeouts(suite) -> [];
+many_timeouts(Config) when is_list(Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ ok = odbc:commit(Ref, commit),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+
+ _Pid = spawn_link(?MODULE, update_table_many_timeouts,
+ [Table, 5000, self()]),
+
+ receive
+ many_timeouts_occurred ->
+ ok
+ end,
+
+ ok = odbc:commit(Ref, commit),
+ ok = odbc:disconnect(Ref),
+ ok.
+
+
+update_table_many_timeouts(Table, TimeOut, Pid) ->
+
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+ UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
+
+ ok = loop_many_timouts(Ref, UpdateQuery, TimeOut),
+
+ Pid ! many_timeouts_occurred,
+
+ ok = odbc:disconnect(Ref),
+ ok.
+
+
+loop_many_timouts(Ref, UpdateQuery, TimeOut) ->
+ case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
+ {'EXIT',timeout} ->
+ loop_many_timouts(Ref, UpdateQuery, TimeOut);
+ {updated, 1} ->
+ test_server:fail(database_locker_failed);
+ {error, connection_closed} ->
+ ok
+ end.
+%%-------------------------------------------------------------------------
+timeout_reset(doc) ->
+ ["Check that the number of consecutive timouts is reset to 0 when "
+ "a successful call to the database is made."];
+timeout_reset(suite) -> [];
+timeout_reset(Config) when is_list(Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ ok = odbc:commit(Ref, commit),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(2,'baz')"),
+
+
+ Pid = spawn_link(?MODULE, update_table_timeout_reset,
+ [Table, 5000, self()]),
+
+ receive
+ many_timeouts_occurred ->
+ ok
+ end,
+
+ ok = odbc:commit(Ref, commit),
+ Pid ! continue,
+
+ receive
+ altered ->
+ ok
+ end,
+
+ {selected, Fields, [{"foobar"}]} =
+ odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 1"),
+ ["DATA"] = odbc_test_lib:to_upper(Fields),
+
+ ok = odbc:commit(Ref, commit),
+ ok = odbc:disconnect(Ref),
+ ok.
+
+update_table_timeout_reset(Table, TimeOut, Pid) ->
+
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+ UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
+
+ ok = loop_timout_reset(Ref, UpdateQuery, TimeOut,
+ ?MAX_SEQ_TIMEOUTS-1),
+
+ Pid ! many_timeouts_occurred,
+
+ receive
+ continue ->
+ ok
+ end,
+
+ {selected, Fields, [{"baz"}]} =
+ odbc:sql_query(Ref, "SELECT DATA FROM " ++ Table ++ " WHERE ID = 2"),
+ ["DATA"] = odbc_test_lib:to_upper(Fields),
+
+ {updated,1} = odbc:sql_query(Ref, UpdateQuery, TimeOut),
+
+ ok = odbc:commit(Ref, commit),
+
+ Pid ! altered,
+
+ ok = odbc:disconnect(Ref),
+
+ ok.
+
+loop_timout_reset(_, _, _, 0) ->
+ ok;
+
+loop_timout_reset(Ref, UpdateQuery, TimeOut, NumTimeouts) ->
+ case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
+ {'EXIT',timeout} ->
+ loop_timout_reset(Ref, UpdateQuery,
+ TimeOut, NumTimeouts - 1);
+ {updated, 1} ->
+ test_server:fail(database_locker_failed);
+ {error, connection_closed} ->
+ test_server:fail(connection_closed_premature)
+ end.
+
+%%-------------------------------------------------------------------------
+
+disconnect_on_timeout(doc) ->
+ ["Check that disconnect after a time out works properly"];
+disconnect_on_timeout(suite) -> [];
+disconnect_on_timeout(Config) when is_list(Config) ->
+
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ ok = odbc:commit(Ref, commit),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+
+
+ _Pid = spawn_link(?MODULE, update_table_disconnect_on_timeout,
+ [Table, 5000, self()]),
+ receive
+ ok ->
+ ok = odbc:commit(Ref, commit);
+ nok ->
+ test_server:fail(database_locker_failed)
+ end.
+
+update_table_disconnect_on_timeout(Table, TimeOut, Pid) ->
+
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{auto_commit, off}]),
+ UpdateQuery = "UPDATE " ++ Table ++ " SET DATA = 'foobar' WHERE ID = 1",
+
+ case catch odbc:sql_query(Ref, UpdateQuery, TimeOut) of
+ {'EXIT', timeout} ->
+ ok = odbc:disconnect(Ref),
+ Pid ! ok;
+ {updated, 1} ->
+ Pid ! nok
+ end.
+
+%%-------------------------------------------------------------------------
+connection_closed(doc) ->
+ ["Checks that you get an appropriate error message if you try to"
+ " use a connection that has been closed"];
+connection_closed(suite) -> [];
+connection_closed(Config) when is_list(Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+
+ Table = ?config(tableName, Config),
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA char(10), PRIMARY KEY(ID))"),
+
+ ok = odbc:disconnect(Ref),
+
+ {error, connection_closed} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+ {error, connection_closed} =
+ odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+ {error, connection_closed} = odbc:first(Ref),
+ {error, connection_closed} = odbc:last(Ref),
+ {error, connection_closed} = odbc:next(Ref),
+ {error, connection_closed} = odbc:prev(Ref),
+ {error, connection_closed} = odbc:select(Ref, next, 3),
+ {error, connection_closed} = odbc:commit(Ref, commit),
+ ok.
+
+%%-------------------------------------------------------------------------
+disable_scrollable_cursors(doc) ->
+ ["Test disabling of scrollable cursors."];
+disable_scrollable_cursors(suite) -> [];
+disable_scrollable_cursors(Config) when is_list(Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{scrollable_cursors, off}]),
+
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ {ok, _} = odbc:select_count(Ref, "SELECT ID FROM " ++ Table),
+
+ NextResult = ?RDBMS:selected_ID(1, next),
+
+ test_server:format("Expected: ~p~n", [NextResult]),
+
+ Result = odbc:next(Ref),
+ test_server:format("Got: ~p~n", [Result]),
+ NextResult = Result,
+
+ {error, scrollable_cursors_disabled} = odbc:first(Ref),
+ {error, scrollable_cursors_disabled} = odbc:last(Ref),
+ {error, scrollable_cursors_disabled} = odbc:prev(Ref),
+ {error, scrollable_cursors_disabled} =
+ odbc:select(Ref, {relative, 2}, 5),
+ {error, scrollable_cursors_disabled} =
+ odbc:select(Ref, {absolute, 2}, 5),
+
+ {selected, _ColNames,[]} = odbc:select(Ref, next, 1),
+ ok.
+
+%%-------------------------------------------------------------------------
+return_rows_as_lists(doc)->
+ ["Test the option that a row may be returned as a list instead "
+ "of a tuple. Too be somewhat backward compatible."];
+return_rows_as_lists(suite) -> [];
+return_rows_as_lists(Config) when is_list(Config) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{tuple_row, off}]),
+
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), PRIMARY KEY(ID))"),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(2,'foo')"),
+
+ ListRows = ?RDBMS:selected_list_rows(),
+ ListRows =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+ First = ?RDBMS:first_list_rows(),
+ Last = ?RDBMS:last_list_rows(),
+ Prev = ?RDBMS:prev_list_rows(),
+ Next = ?RDBMS:next_list_rows(),
+
+ Last = odbc:last(Ref),
+ Prev = odbc:prev(Ref),
+ First = odbc:first(Ref),
+ Next = odbc:next(Ref),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+api_missuse(doc)->
+ ["Test that behaviour of the control process if the api is abused"];
+api_missuse(suite) -> [];
+api_missuse(Config) when is_list(Config)->
+
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ %% Serious programming fault, connetion will be shut down
+ gen_server:call(Ref, {self(), foobar, 10}, infinity),
+ test_server:sleep(10),
+ undefined = process_info(Ref, status),
+
+ {ok, Ref2} = odbc:connect(?RDBMS:connection_string(), []),
+ %% Serious programming fault, connetion will be shut down
+ gen_server:cast(Ref2, {self(), foobar, 10}),
+ test_server:sleep(10),
+ undefined = process_info(Ref2, status),
+
+ {ok, Ref3} = odbc:connect(?RDBMS:connection_string(), []),
+ %% Could be an innocent misstake the connection lives.
+ Ref3 ! foobar,
+ test_server:sleep(10),
+ {status, _} = process_info(Ref3, status),
+ ok.
+
diff --git a/lib/odbc/test/odbc_data_type_SUITE.erl b/lib/odbc/test/odbc_data_type_SUITE.erl
new file mode 100644
index 0000000000..7d4a0ca15f
--- /dev/null
+++ b/lib/odbc/test/odbc_data_type_SUITE.erl
@@ -0,0 +1,1498 @@
+%%
+%% %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(odbc_data_type_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include_lib("stdlib/include/ms_transform.hrl").
+-include("test_server_line.hrl").
+-include("odbc_test.hrl").
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ["Tests data types"];
+all(suite) ->
+ case odbc_test_lib:odbc_check() of
+ ok -> all();
+ Other -> {skip,Other}
+ end.
+
+all() ->
+ [char, int, floats, dec_and_num, timestamp].
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ application:start(odbc),
+ [{tableName, odbc_test_lib:unique_table_name()} | 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) ->
+ application:stop(odbc),
+ 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) ->
+ case atom_to_list(Case) of
+ "binary" ++ _ ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{binary_strings, on}]);
+ "unicode" ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(),
+ [{binary_strings, on}]);
+ _ ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), [])
+ end,
+ Dog = test_server:timetrap(?default_timeout),
+ Temp = lists:keydelete(connection_ref, 1, Config),
+ NewConfig = lists:keydelete(watchdog, 1, Temp),
+ [{watchdog, Dog}, {connection_ref, Ref} | 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(_TestCase, Config) ->
+ Ref = ?config(connection_ref, Config),
+ ok = odbc:disconnect(Ref),
+ %% Clean up if needed
+ Table = ?config(tableName, Config),
+ {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []),
+ odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
+ odbc:disconnect(NewRef),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+char(doc) ->
+ ["Tests char data types"];
+
+char(suite) ->
+ [char_fixed_lower_limit, char_fixed_upper_limit,
+ char_fixed_padding, varchar_lower_limit, varchar_upper_limit,
+ varchar_no_padding, text_lower_limit, text_upper_limit, unicode
+ ].
+
+char_fixed_lower_limit(doc) ->
+ ["Tests fixed length char data type lower boundaries."];
+char_fixed_lower_limit(suite) ->
+ [];
+char_fixed_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Below limit
+ {error, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ (?RDBMS:fixed_char_min() - 1))),
+ %% Lower limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_min())),
+
+ %% Right length data
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:fixed_char_min())
+ ++ "')"),
+ %% Select data
+ {selected, Fields,[{"a"}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:fixed_char_min()
+ + 1))
+ ++ "')"),
+ ok.
+%%-------------------------------------------------------------------------
+
+char_fixed_upper_limit(doc) ->
+ ["Tests fixed length char data type upper boundaries."];
+char_fixed_upper_limit(suite) ->
+ [];
+char_fixed_upper_limit(Config) when is_list(Config) ->
+
+ case ?RDBMS of
+ postgres ->
+ {skip, "Limit unknown"};
+ _ ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Upper limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_max())),
+ {updated, _} =
+ odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ ?RDBMS:fixed_char_max())
+ ++ "')"),
+ %% Select data
+ {selected, Fields, [{CharStr}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = length(CharStr) == ?RDBMS:fixed_char_max(),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:fixed_char_max()
+ + 1))
+ ++ "')"),
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ %% Above limit
+ {error, _} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ (?RDBMS:fixed_char_max() + 1))),
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+
+char_fixed_padding(doc) ->
+ ["Tests that data that is shorter than the given size is padded "
+ "with blanks."];
+char_fixed_padding(suite) ->
+ [];
+char_fixed_padding(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Data should be padded with blanks
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_max())),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ ?RDBMS:fixed_char_min())
+ ++ "')"),
+
+ {selected, Fields, [{CharStr}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = length(CharStr) == ?RDBMS:fixed_char_max(),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+%%-------------------------------------------------------------------------
+
+varchar_lower_limit(doc) ->
+ ["Tests variable length char data type lower boundaries."];
+varchar_lower_limit(suite) ->
+ [];
+varchar_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Below limit
+ {error, _} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_min() - 1)),
+ %% Lower limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_min())),
+
+ %% Right length data
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:var_char_min())
+ ++ "')"),
+ %% Select data
+ {selected, Fields, [{"a"}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:var_char_min()+1))
+ ++ "')"),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+varchar_upper_limit(doc) ->
+ ["Tests variable length char data type upper boundaries."];
+varchar_upper_limit(suite) ->
+ [];
+varchar_upper_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ case ?RDBMS of
+ oracle ->
+ {skip, "Known bug in database"};
+ postgres ->
+ {skip, "Limit unknown"};
+ _ ->
+ %% Upper limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_max())),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ ?RDBMS:var_char_max())
+ ++ "')"),
+
+ {selected, Fields, [{CharStr}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = length(CharStr) == ?RDBMS:var_char_max(),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:var_char_max()+1))
+ ++ "')"),
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ %% Above limit
+ {error, _} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ (?RDBMS:var_char_max() + 1))),
+ ok
+ end.
+%%-------------------------------------------------------------------------
+
+varchar_no_padding(doc) ->
+ ["Tests that data that is shorter than the given max size is not padded "
+ "with blanks."];
+varchar_no_padding(suite) ->
+ [];
+varchar_no_padding(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Data should NOT be padded with blanks
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_max())),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:var_char_min())
+ ++ "')"),
+
+ {selected, Fields, [{CharStr}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = length(CharStr) /= ?RDBMS:var_char_max(),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+text_lower_limit(doc) ->
+ ["Tests 'long' char data type lower boundaries."];
+text_lower_limit(suite) ->
+ [];
+text_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_text_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:text_min())
+ ++ "')"),
+
+ {selected, Fields, [{"a"}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+text_upper_limit(doc) ->
+ [];
+text_upper_limit(suite) ->
+ [];
+text_upper_limit(Config) when is_list(Config) ->
+
+ {skip,"Consumes too much resources" }.
+%% Ref = ?config(connection_ref, Config),
+%% Table = ?config(tableName, Config),
+
+%% {updated, _} = % Value == 0 || -1 driver dependent!
+%% odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+%% ?RDBMS:create_text_table()),
+%% {updated, _} =
+%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+%% "'" ++ string:chars($a, ?RDBMS:text_max())
+%% ++ "')"),
+
+%% {selected, Fields, [{CharStr}]} =
+%% odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+%% length(CharStr) == ?RDBMS:text_max(),
+%% ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+%% {error, _} =
+%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+%% "'" ++ string:chars($a, (?RDBMS:text_max()+1))
+%% ++ "')"),
+%% ok.
+
+%%-------------------------------------------------------------------------
+binary_char(doc) ->
+ ["Tests char data types returned as erlang binaries"];
+
+binary_char(suite) ->
+ [binary_char_fixed_lower_limit, binary_char_fixed_upper_limit,
+ binary_char_fixed_padding, binary_varchar_lower_limit, binary_varchar_upper_limit,
+ binary_varchar_no_padding, binary_text_lower_limit, binary_text_upper_limit, unicode
+ ].
+
+binary_char_fixed_lower_limit(doc) ->
+ ["Tests fixed length char data type lower boundaries."];
+binary_char_fixed_lower_limit(suite) ->
+ [];
+binary_char_fixed_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Below limit
+ {error, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ (?RDBMS:fixed_char_min() - 1))),
+ %% Lower limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_min())),
+
+ %% Right length data
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:fixed_char_min())
+ ++ "')"),
+ %% Select data
+ {selected, Fields,[{<<"a">>}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:fixed_char_min()
+ + 1))
+ ++ "')"),
+ ok.
+%%-------------------------------------------------------------------------
+
+binary_char_fixed_upper_limit(doc) ->
+ ["Tests fixed length char data type upper boundaries."];
+binary_char_fixed_upper_limit(suite) ->
+ [];
+binary_char_fixed_upper_limit(Config) when is_list(Config) ->
+
+ case ?RDBMS of
+ postgres ->
+ {skip, "Limit unknown"};
+ _ ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Upper limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_max())),
+ {updated, _} =
+ odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ ?RDBMS:fixed_char_max())
+ ++ "')"),
+ %% Select data
+ {selected, Fields, [{CharBin}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = size(CharBin) == ?RDBMS:fixed_char_max(),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:fixed_char_max()
+ + 1))
+ ++ "')"),
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ %% Above limit
+ {error, _} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ (?RDBMS:fixed_char_max() + 1))),
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+
+binary_char_fixed_padding(doc) ->
+ ["Tests that data that is shorter than the given size is padded "
+ "with blanks."];
+binary_char_fixed_padding(suite) ->
+ [];
+binary_char_fixed_padding(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Data should be padded with blanks
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_fixed_char_table(
+ ?RDBMS:fixed_char_max())),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ ?RDBMS:fixed_char_min())
+ ++ "')"),
+
+ {selected, Fields, [{CharBin}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = size(CharBin) == ?RDBMS:fixed_char_max(),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+%%-------------------------------------------------------------------------
+
+binary_varchar_lower_limit(doc) ->
+ ["Tests variable length char data type lower boundaries."];
+binary_varchar_lower_limit(suite) ->
+ [];
+binary_varchar_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Below limit
+ {error, _} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_min() - 1)),
+ %% Lower limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_min())),
+
+ %% Right length data
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:var_char_min())
+ ++ "')"),
+ %% Select data
+ {selected, Fields, [{<<"a">>}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:var_char_min()+1))
+ ++ "')"),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+binary_varchar_upper_limit(doc) ->
+ ["Tests variable length char data type upper boundaries."];
+binary_varchar_upper_limit(suite) ->
+ [];
+binary_varchar_upper_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ case ?RDBMS of
+ oracle ->
+ {skip, "Known bug in database"};
+ postgres ->
+ {skip, "Limit unknown"};
+ _ ->
+ %% Upper limit
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_max())),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ ?RDBMS:var_char_max())
+ ++ "')"),
+
+ {selected, Fields, [{CharBin}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = size(CharBin) == ?RDBMS:var_char_max(),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Too long data
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a,
+ (?RDBMS:var_char_max()+1))
+ ++ "')"),
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ %% Above limit
+ {error, _} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ (?RDBMS:var_char_max() + 1))),
+ ok
+ end.
+%%-------------------------------------------------------------------------
+
+binary_varchar_no_padding(doc) ->
+ ["Tests that data that is shorter than the given max size is not padded "
+ "with blanks."];
+binary_varchar_no_padding(suite) ->
+ [];
+binary_varchar_no_padding(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ %% Data should NOT be padded with blanks
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_var_char_table(
+ ?RDBMS:var_char_max())),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:var_char_min())
+ ++ "')"),
+
+ {selected, Fields, [{CharBin}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ true = size(CharBin) /= ?RDBMS:var_char_max(),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+binary_text_lower_limit(doc) ->
+ ["Tests 'long' char data type lower boundaries."];
+binary_text_lower_limit(suite) ->
+ [];
+binary_text_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_text_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ string:chars($a, ?RDBMS:text_min())
+ ++ "')"),
+
+ {selected, Fields, [{<<"a">>}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+binary_text_upper_limit(doc) ->
+ [];
+binary_text_upper_limit(suite) ->
+ [];
+binary_text_upper_limit(Config) when is_list(Config) ->
+
+ {skip,"Consumes too much resources" }.
+%% Ref = ?config(connection_ref, Config),
+%% Table = ?config(tableName, Config),
+
+%% {updated, _} = % Value == 0 || -1 driver dependent!
+%% odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+%% ?RDBMS:create_text_table()),
+%% {updated, _} =
+%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+%% "'" ++ string:chars($a, ?RDBMS:text_max())
+%% ++ "')"),
+
+%% {selected, Fields, [{CharBin}]} =
+%% odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+%% size(CharBin) == ?RDBMS:text_max(),
+%% ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+%% {error, _} =
+%% odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+%% "'" ++ string:chars($a, (?RDBMS:text_max()+1))
+%% ++ "')"),
+%% ok.
+
+
+%%-------------------------------------------------------------------------
+
+int(doc) ->
+ ["Tests integer data types"];
+
+int(suite) ->
+ [tiny_int_lower_limit, tiny_int_upper_limit, small_int_lower_limit,
+ small_int_upper_limit, int_lower_limit, int_upper_limit,
+ big_int_lower_limit, big_int_upper_limit, bit_false, bit_true].
+
+%%-------------------------------------------------------------------------
+
+tiny_int_lower_limit(doc) ->
+ ["Tests integer of type tinyint."];
+tiny_int_lower_limit(suite) ->
+ [];
+tiny_int_lower_limit(Config) when is_list(Config) ->
+ case ?RDBMS of
+ postgres ->
+ {skip, "Type tiniyint not supported"};
+ _ ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_tiny_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:tiny_int_min())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:tiny_int_min_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:tiny_int_min()
+ - 1)
+ ++ "')"),
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+
+tiny_int_upper_limit(doc) ->
+ ["Tests integer of type tinyint."];
+tiny_int_upper_limit(suite) ->
+ [];
+tiny_int_upper_limit(Config) when is_list(Config) ->
+ case ?RDBMS of
+ postgres ->
+ {skip, "Type tiniyint not supported"};
+ _ ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_tiny_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:tiny_int_max())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:tiny_int_max_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:tiny_int_max()
+ + 1)
+ ++ "')"),
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+
+small_int_lower_limit(doc) ->
+ ["Tests integer of type smallint."];
+small_int_lower_limit(suite) ->
+ [];
+small_int_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_small_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:small_int_min())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:small_int_min_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:small_int_min()
+ - 1)
+ ++ "')"),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+small_int_upper_limit(doc) ->
+ ["Tests integer of type smallint."];
+small_int_upper_limit(suite) ->
+ [];
+small_int_upper_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_small_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:small_int_max())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:small_int_max_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref,"INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:small_int_max()
+ + 1)
+ ++ "')"),
+ ok.
+
+%%-------------------------------------------------------------------------
+int_lower_limit(doc) ->
+ ["Tests integer of type int."];
+int_lower_limit(suite) ->
+ [];
+int_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:int_min())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:int_min_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:int_min() - 1)
+ ++ "')"),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+int_upper_limit(doc) ->
+ ["Tests integer of type int."];
+int_upper_limit(suite) ->
+ [];
+int_upper_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:int_max())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:int_max_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:int_max() + 1)
+ ++ "')"),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+big_int_lower_limit(doc) ->
+ ["Tests integer of type bigint"];
+big_int_lower_limit(suite) ->
+ [];
+big_int_lower_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_big_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:big_int_min())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:big_int_min_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:big_int_min()
+ - 1)
+ ++ "')"),
+ ok.
+
+%%-------------------------------------------------------------------------
+
+big_int_upper_limit(doc) ->
+ ["Tests integer of type bigint."];
+big_int_upper_limit(suite) ->
+ [];
+big_int_upper_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_big_int_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:big_int_max())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:big_int_max_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:big_int_max()
+ + 1)
+ ++ "')"),
+ ok.
+%%-------------------------------------------------------------------------
+
+bit_false(doc) ->
+ [""];
+bit_false(suite) ->
+ [];
+bit_false(Config) when is_list(Config) ->
+ case ?RDBMS of
+ oracle ->
+ {skip, "Not supported by driver"};
+ _ ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_bit_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:bit_false())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:bit_false_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(-1)
+ ++ "')"),
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+
+bit_true(doc) ->
+ [""];
+bit_true(suite) ->
+ [];
+bit_true(Config) when is_list(Config) ->
+ case ?RDBMS of
+ oracle ->
+ {skip, "Not supported by driver"};
+ _ ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_bit_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(?RDBMS:bit_true())
+ ++ "')"),
+
+ SelectResult = ?RDBMS:bit_true_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ integer_to_list(-1)
+ ++ "')"),
+ ok
+ end.
+
+%%-------------------------------------------------------------------------
+
+floats(doc) ->
+ ["Test the datatype float."];
+floats(suite) ->
+ [float_lower_limit, float_upper_limit, float_zero, real_zero].
+
+%%-------------------------------------------------------------------------
+float_lower_limit(doc) ->
+ [""];
+float_lower_limit(suite) ->
+ [];
+float_lower_limit(Config) when is_list(Config) ->
+
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_float_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ float_to_list(
+ ?RDBMS:float_min())
+ ++ "')"),
+ {selected,[_ColName],[{MinFloat}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ true = ?RDBMS:float_min() == MinFloat,
+
+ case ?RDBMS of
+ oracle ->
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_float_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "INSERT INTO " ++ Table ++" VALUES(" ++
+ ?RDBMS:float_underflow() ++ ")"),
+
+ SelectResult = ?RDBMS:float_zero_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table);
+ _ ->
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ ?RDBMS:float_underflow() ++ ")")
+ end,
+ ok.
+
+
+%%-------------------------------------------------------------------------
+float_upper_limit(doc) ->
+ [""];
+float_upper_limit(suite) ->
+ [];
+float_upper_limit(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_float_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ "'" ++ float_to_list(
+ ?RDBMS:float_max())
+ ++ "')"),
+
+
+ {selected,[_ColName],[{MaxFloat}]}
+ = odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+
+ true = ?RDBMS:float_max() == MaxFloat,
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(" ++
+ ?RDBMS:float_overflow() ++ ")"),
+ ok.
+
+%%-------------------------------------------------------------------------
+float_zero(doc) ->
+ ["Test the float value zero."];
+float_zero(suite) ->
+ [];
+float_zero(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_float_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES('0')"),
+
+ SelectResult = ?RDBMS:float_zero_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ok.
+%%-------------------------------------------------------------------------
+real_zero(doc) ->
+ ["Test the real value zero."];
+real_zero(suite) ->
+ [];
+real_zero(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ case ?RDBMS of
+ oracle ->
+ {skip, "Not supported in Oracle"};
+ _ ->
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_real_table()),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES('0')"),
+
+ SelectResult = ?RDBMS:real_zero_selected(),
+ SelectResult =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ok
+ end.
+%%-------------------------------------------------------------------------
+dec_and_num(doc) ->
+ ["Tests decimal and numeric datatypes."];
+dec_and_num(suite) ->
+ [dec_long, dec_double, dec_bignum, num_long, num_double, num_bignum].
+%%------------------------------------------------------------------------
+dec_long(doc) ->
+ [""];
+dec_long(suit) ->
+ [];
+dec_long(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (9,0))"),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields, [{2}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+%%------------------------------------------------------------------------
+dec_double(doc) ->
+ [""];
+dec_double(suit) ->
+ [];
+dec_double(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (10,0))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields, [{2.00000}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (15,0))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields1, [{2.00000}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields1),
+
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (15, 1))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields2, [{1.60000}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields2),
+ ok.
+
+%%------------------------------------------------------------------------
+dec_bignum(doc) ->
+ [""];
+dec_bignum(suit) ->
+ [];
+dec_bignum(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (16,0))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields, [{"2"}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (16,1))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields1, [{"1.6"}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields1),
+ ok.
+%%------------------------------------------------------------------------
+num_long(doc) ->
+ [""];
+num_long(suit) ->
+ [];
+num_long(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (9,0))"),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.5)"),
+
+ {selected, Fields, [{2}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+ ok.
+%%------------------------------------------------------------------------
+num_double(doc) ->
+ [""];
+num_double(suit) ->
+ [];
+num_double(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (10,0))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields, [{2.0000}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (15,0))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields1, [{2.0000}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields1),
+
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (15,1))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields2, [{1.6000}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields2),
+ ok.
+%%------------------------------------------------------------------------
+num_bignum(doc) ->
+ [""];
+num_bignum(suit) ->
+ [];
+num_bignum(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (16,0))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields, [{"2"}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ %% Clean up
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ "(FIELD DECIMAL (16,1))"),
+ {updated, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++" VALUES(1.6)"),
+
+ {selected, Fields1, [{"1.6"}]} =
+ odbc:sql_query(Ref,"SELECT FIELD FROM " ++ Table),
+ ["FIELD"] = odbc_test_lib:to_upper(Fields1),
+ ok.
+
+%%------------------------------------------------------------------------
+unicode(doc) ->
+ ["Test unicode support"];
+unicode(suit) ->
+ [];
+unicode(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_unicode_table()),
+
+ Latin1Data = ["���������",
+ "testasdf",
+ "Row 3",
+ "Row 4",
+ "Row 5",
+ "Row 6",
+ "Row 7",
+ "Row 8",
+ "Row 9",
+ "Row 10",
+ "Row 11",
+ "Row 12"],
+
+ case ?RDBMS of
+ sqlserver ->
+ w_char_support_win(Ref, Table, Latin1Data);
+ postgres ->
+ direct_utf8(Ref, Table, Latin1Data);
+ oracle ->
+ {skip, "not currently supported"}
+ end.
+
+w_char_support_win(Ref, Table, Latin1Data) ->
+ UnicodeIn = lists:map(fun(S) ->
+ unicode:characters_to_binary(S,latin1,{utf16,little})
+ end,
+ Latin1Data),
+
+ test_server:format("UnicodeIn (utf 16): ~p ~n",[UnicodeIn]),
+
+ {updated, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++ "(FIELD) values(?)",
+ [{{sql_wvarchar,50},UnicodeIn}]),
+
+ {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
+
+ test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
+
+ Result = lists:map(fun({Unicode}) ->
+ unicode:characters_to_list(Unicode,{utf16,little})
+ end,
+ UnicodeOut),
+ Latin1Data = Result.
+
+
+direct_utf8(Ref, Table, Latin1Data) ->
+ UnicodeIn = lists:map(fun(String) ->
+ unicode:characters_to_binary(String,latin1,utf8)
+ end,
+ Latin1Data),
+
+ test_server:format("UnicodeIn: ~p ~n",[UnicodeIn]),
+ {updated, _} = odbc:param_query(Ref,"INSERT INTO " ++ Table ++ "(FIELD) values(?)",
+ [{{sql_varchar,50}, UnicodeIn}]),
+
+ {selected,_,UnicodeOut} = odbc:sql_query(Ref,"SELECT * FROM " ++ Table),
+
+ test_server:format("UnicodeOut: ~p~n", [UnicodeOut]),
+
+ Result = lists:map(fun({Char}) ->
+ unicode:characters_to_list(Char,utf8)
+ end, UnicodeOut),
+
+ test_server:format("Result: ~p ~n", [Result]),
+
+ Latin1Data = Result.
+
+%%------------------------------------------------------------------------
+timestamp(doc) ->
+ [""];
+timestamp(suit) ->
+ [];
+timestamp(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_timestamp_table()),
+
+ Data = [calendar:local_time(),
+ {{2009,6,17},{20,54,59}},
+ {{2009,6,18},{20,54,59}},
+ {{2009,6,19},{20,54,59}},
+ {{2009,6,20},{20,54,59}},
+ {{2009,6,21},{20,54,59}}],
+
+ {updated, _} = odbc:param_query(Ref,"INSERT INTO " ++ Table ++ "(FIELD) values(?)",
+ [{sql_timestamp,Data}]),
+
+ %%% Crate list or database table rows
+ TimeStamps = lists:map(fun(Value) -> {Value} end, Data),
+
+ {selected,_, TimeStamps} = odbc:sql_query(Ref, "SELECT * FROM " ++ Table).
diff --git a/lib/odbc/test/odbc_query_SUITE.erl b/lib/odbc/test/odbc_query_SUITE.erl
new file mode 100644
index 0000000000..12b39be3b7
--- /dev/null
+++ b/lib/odbc/test/odbc_query_SUITE.erl
@@ -0,0 +1,1453 @@
+%%
+%% %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(odbc_query_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("odbc_test.hrl").
+
+%%--------------------------------------------------------------------
+%% 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) ->
+ ["Tests SQL queries"];
+all(suite) ->
+ case odbc_test_lib:odbc_check() of
+ ok -> all();
+ Other -> {skip, Other}
+ end.
+
+all() ->
+ [sql_query, first, last, next, prev, select_count,select_next,
+ select_relative, select_absolute, create_table_twice,
+ delete_table_twice, duplicate_key, not_connection_owner,
+ no_result_set, query_error, multiple_select_result_sets,
+ multiple_mix_result_sets, multiple_result_sets_error,
+ parameterized_queries, describe_table,
+ delete_nonexisting_row].
+
+
+%%--------------------------------------------------------------------
+%% 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) when is_list(Config) ->
+ application:start(odbc),
+ [{tableName, odbc_test_lib:unique_table_name()}| 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) ->
+ application:stop(odbc),
+ 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) ->
+ {ok, Ref} = odbc:connect(?RDBMS:connection_string(), []),
+ Dog = test_server:timetrap(?default_timeout),
+ Temp = lists:keydelete(connection_ref, 1, Config),
+ NewConfig = lists:keydelete(watchdog, 1, Temp),
+ [{watchdog, Dog}, {connection_ref, Ref} | 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(_Case, Config) ->
+ Ref = ?config(connection_ref, Config),
+ ok = odbc:disconnect(Ref),
+ %% Clean up if needed
+ Table = ?config(tableName, Config),
+ {ok, NewRef} = odbc:connect(?RDBMS:connection_string(), []),
+ odbc:sql_query(NewRef, "DROP TABLE " ++ Table),
+ odbc:disconnect(NewRef),
+ Dog = ?config(watchdog, Config),
+ test_server:timetrap_cancel(Dog),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Test cases starts here.
+%%-------------------------------------------------------------------------
+sql_query(doc)->
+ ["Test the common cases"];
+sql_query(suite) -> [];
+sql_query(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10))"),
+
+ {updated, Count} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ true = odbc_test_lib:check_row_count(1, Count),
+
+ InsertResult = ?RDBMS:insert_result(),
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {updated, NewCount} =
+ odbc:sql_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foo' WHERE ID = 1"),
+
+ true = odbc_test_lib:check_row_count(1, NewCount),
+
+ UpdateResult = ?RDBMS:update_result(),
+ UpdateResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {updated, NewCount1} = odbc:sql_query(Ref, "DELETE FROM " ++ Table ++
+ " WHERE ID = 1"),
+
+ true = odbc_test_lib:check_row_count(1, NewCount1),
+
+ {selected, Fields, []} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["ID","DATA"] = odbc_test_lib:to_upper(Fields),
+ ok.
+
+%%-------------------------------------------------------------------------
+select_count(doc) ->
+ ["Tests select_count/[2,3]'s timeout, "
+ " select_count's functionality will be better tested by other tests "
+ " such as first."];
+select_count(sute) -> [];
+select_count(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ true = odbc_test_lib:check_row_count(1, Count),
+ {ok, _} =
+ odbc:select_count(Ref, "SELECT * FROM " ++ Table, ?TIMEOUT),
+ {'EXIT', {function_clause, _}} =
+ (catch odbc:select_count(Ref, "SELECT * FROM ", -1)),
+ ok.
+%%-------------------------------------------------------------------------
+first(doc) ->
+ ["Tests first/[1,2]"];
+first(suite) -> [];
+first(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ true = odbc_test_lib:check_row_count(1, Count),
+ {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2)"),
+ true = odbc_test_lib:check_row_count(1, NewCount),
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+
+ FirstResult = ?RDBMS:selected_ID(1, first),
+ FirstResult = odbc:first(Ref),
+ FirstResult = odbc:first(Ref, ?TIMEOUT),
+ {'EXIT', {function_clause, _}} = (catch odbc:first(Ref, -1)),
+ ok.
+
+%%-------------------------------------------------------------------------
+last(doc) ->
+ ["Tests last/[1,2]"];
+last(suite) -> [];
+last(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ true = odbc_test_lib:check_row_count(1, Count),
+ {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2)"),
+ true = odbc_test_lib:check_row_count(1, NewCount),
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+ LastResult = ?RDBMS:selected_ID(2, last),
+ LastResult = odbc:last(Ref),
+
+ LastResult = odbc:last(Ref, ?TIMEOUT),
+ {'EXIT', {function_clause, _}} = (catch odbc:last(Ref, -1)),
+ ok.
+
+%%-------------------------------------------------------------------------
+next(doc) ->
+ ["Tests next/[1,2]"];
+next(suite) -> [];
+next(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ true = odbc_test_lib:check_row_count(1, Count),
+ {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2)"),
+ true = odbc_test_lib:check_row_count(1, NewCount),
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+ NextResult = ?RDBMS:selected_ID(1, next),
+ NextResult = odbc:next(Ref),
+ NextResult2 = ?RDBMS:selected_ID(2, next),
+ NextResult2 = odbc:next(Ref, ?TIMEOUT),
+ {'EXIT', {function_clause, _}} = (catch odbc:next(Ref, -1)),
+ ok.
+%%-------------------------------------------------------------------------
+prev(doc) ->
+ ["Tests prev/[1,2]"];
+prev(suite) -> [];
+prev(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, Count} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ true = odbc_test_lib:check_row_count(1, Count),
+ {updated, NewCount} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2)"),
+ true = odbc_test_lib:check_row_count(1, NewCount),
+
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+ odbc:last(Ref), % Position cursor last so there will be a prev
+ PrevResult = ?RDBMS:selected_ID(1, prev),
+ PrevResult = odbc:prev(Ref),
+
+ odbc:last(Ref), % Position cursor last so there will be a prev
+ PrevResult = odbc:prev(Ref, ?TIMEOUT),
+ {'EXIT', {function_clause, _}} = (catch odbc:prev(Ref, -1)),
+ ok.
+%%-------------------------------------------------------------------------
+select_next(doc) ->
+ ["Tests select/[4,5] with CursorRelation = next "];
+select_next(suit) -> [];
+select_next(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(3)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(4)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(5)"),
+
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+ SelectResult1 = ?RDBMS:selected_next_N(1),
+ SelectResult1 = odbc:select(Ref, next, 3),
+
+ %% Test that selecting stops at the end of the result set
+ SelectResult2 = ?RDBMS:selected_next_N(2),
+ SelectResult2 = odbc:select(Ref, next, 3, ?TIMEOUT),
+ {'EXIT',{function_clause, _}} =
+ (catch odbc:select(Ref, next, 2, -1)),
+
+ %% If you try fetching data beyond the the end of result set,
+ %% you get an empty list.
+ {selected, Fields, []} = odbc:select(Ref, next, 1),
+
+ ["ID"] = odbc_test_lib:to_upper(Fields),
+ ok.
+
+%%-------------------------------------------------------------------------
+select_relative(doc) ->
+ ["Tests select/[4,5] with CursorRelation = relative "];
+select_relative(suit) -> [];
+select_relative(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(3)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(4)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(5)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(6)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(7)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(8)"),
+
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+ SelectResult1 = ?RDBMS:selected_relative_N(1),
+ SelectResult1 = odbc:select(Ref, {relative, 2}, 3),
+
+ %% Test that selecting stops at the end of the result set
+ SelectResult2 = ?RDBMS:selected_relative_N(2),
+ SelectResult2 = odbc:select(Ref, {relative, 3}, 3, ?TIMEOUT),
+ {'EXIT',{function_clause, _}} =
+ (catch odbc:select(Ref, {relative, 3} , 2, -1)),
+ ok.
+
+%%-------------------------------------------------------------------------
+select_absolute(doc) ->
+ ["Tests select/[4,5] with CursorRelation = absolute "];
+select_absolute(suit) -> [];
+select_absolute(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer)"),
+
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(3)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(4)"),
+ {updated, 1} = odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(5)"),
+ {ok, _} = odbc:select_count(Ref, "SELECT * FROM " ++ Table),
+
+ SelectResult1 = ?RDBMS:selected_absolute_N(1),
+ SelectResult1 = odbc:select(Ref, {absolute, 1}, 3),
+
+ %% Test that selecting stops at the end of the result set
+ SelectResult2 = ?RDBMS:selected_absolute_N(2),
+ SelectResult2 = odbc:select(Ref, {absolute, 1}, 6, ?TIMEOUT),
+ {'EXIT',{function_clause, _}} =
+ (catch odbc:select(Ref, {absolute, 1}, 2, -1)),
+ ok.
+
+%%-------------------------------------------------------------------------
+create_table_twice(doc) ->
+ ["Test what happens if you try to create the same table twice."];
+create_table_twice(suite) -> [];
+create_table_twice(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10))"),
+ {error, Error} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10))"),
+ is_driver_error(Error),
+ ok.
+
+%%-------------------------------------------------------------------------
+delete_table_twice(doc) ->
+ ["Test what happens if you try to delete the same table twice."];
+delete_table_twice(suite) -> [];
+delete_table_twice(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10))"),
+ {updated, _} = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+ {error, Error} = odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+ is_driver_error(Error),
+ ok.
+
+%-------------------------------------------------------------------------
+duplicate_key(doc) ->
+ ["Test what happens if you try to use the same key twice"];
+duplicate_key(suit) -> [];
+duplicate_key(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA char(10), PRIMARY KEY(ID))"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ {error, Error} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'foo')"),
+ is_driver_error(Error),
+ ok.
+
+%%-------------------------------------------------------------------------
+not_connection_owner(doc) ->
+ ["Test what happens if a process that did not start the connection"
+ " tries to acess it."];
+not_connection_owner(suite) -> [];
+not_connection_owner(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ spawn_link(?MODULE, not_owner, [self(), Ref, Table]),
+
+ receive
+ continue ->
+ ok
+ end.
+
+not_owner(Pid, Ref, Table) ->
+ {error, process_not_owner_of_odbc_connection} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++ " (ID integer)"),
+
+ {error, process_not_owner_of_odbc_connection} =
+ odbc:disconnect(Ref),
+
+ Pid ! continue.
+
+%%-------------------------------------------------------------------------
+no_result_set(doc) ->
+ ["Tests what happens if you try to use a function that needs an "
+ "associated result set when there is none."];
+no_result_set(suite) -> [];
+no_result_set(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+
+ {error, result_set_does_not_exist} = odbc:first(Ref),
+ {error, result_set_does_not_exist} = odbc:last(Ref),
+ {error, result_set_does_not_exist} = odbc:next(Ref),
+ {error, result_set_does_not_exist} = odbc:prev(Ref),
+ {error, result_set_does_not_exist} = odbc:select(Ref, next, 1),
+ {error, result_set_does_not_exist} =
+ odbc:select(Ref, {absolute, 2}, 1),
+ {error, result_set_does_not_exist} =
+ odbc:select(Ref, {relative, 2}, 1),
+ ok.
+%%-------------------------------------------------------------------------
+query_error(doc) ->
+ ["Test what happens if there is an error in the query."];
+query_error(suite) ->
+ [];
+query_error(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA char(10), PRIMARY KEY(ID))"),
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++ " VALUES(1,'bar')"),
+
+ {error, _} =
+ odbc:sql_query(Ref, "INSERT ONTO " ++ Table ++ " VALUES(1,'bar')"),
+ ok.
+
+%%-------------------------------------------------------------------------
+multiple_select_result_sets(doc) ->
+ ["Test what happens if you have a batch of select queries."];
+multiple_select_result_sets(suite) ->
+ [];
+multiple_select_result_sets(Config) when is_list(Config) ->
+ case ?RDBMS of
+ sqlserver ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), "
+ "PRIMARY KEY(ID))"),
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1,'bar')"),
+
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2, 'foo')"),
+
+ MultipleResult = ?RDBMS:multiple_select(),
+
+ MultipleResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table ++
+ "; SELECT DATA FROM "++ Table ++
+ " WHERE ID=2"),
+ ok;
+ _ ->
+ {skip, "multiple result_set not supported"}
+ end.
+
+%%-------------------------------------------------------------------------
+multiple_mix_result_sets(doc) ->
+ ["Test what happens if you have a batch of select and other type of"
+ " queries."];
+multiple_mix_result_sets(suite) ->
+ [];
+multiple_mix_result_sets(Config) when is_list(Config) ->
+ case ?RDBMS of
+ sqlserver ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), "
+ "PRIMARY KEY(ID))"),
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1,'bar')"),
+
+ MultipleResult = ?RDBMS:multiple_mix(),
+
+ MultipleResult =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(2,'foo'); UPDATE " ++ Table ++
+ " SET DATA = 'foobar' WHERE ID =1;SELECT "
+ "* FROM "
+ ++ Table ++ ";DELETE FROM " ++ Table ++
+ " WHERE ID =1; SELECT DATA FROM " ++ Table),
+ ok;
+ _ ->
+ {skip, "multiple result_set not supported"}
+ end.
+%%-------------------------------------------------------------------------
+multiple_result_sets_error(doc) ->
+ ["Test what happens if one of the batched queries fails."];
+multiple_result_sets_error(suite) ->
+ [];
+multiple_result_sets_error(Config) when is_list(Config) ->
+ case ?RDBMS of
+ sqlserver ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID integer, DATA varchar(10), "
+ "PRIMARY KEY(ID))"),
+ {updated, 1} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1,'bar')"),
+
+ {error, Error} =
+ odbc:sql_query(Ref, "INSERT INTO " ++ Table ++
+ " VALUES(1,'foo'); SELECT * FROM " ++ Table),
+ is_driver_error(Error),
+
+ {error, NewError} =
+ odbc:sql_query(Ref, "SELECT * FROM "
+ ++ Table ++ ";INSERT INTO " ++ Table ++
+ " VALUES(1,'foo')"),
+ is_driver_error(NewError),
+ ok;
+ _ ->
+ {skip, "multiple result_set not supported"}
+ end.
+
+%%-------------------------------------------------------------------------
+parameterized_queries(doc)->
+ ["Tests diffrent variants of parameterized queries."];
+parameterized_queries(suite) ->
+ %% Note timestamps are inserted with param_query in odbc_data_type_SUITE
+ %% so no need to test this again.
+ [param_integers,
+ param_insert_decimal, param_insert_numeric,
+ param_insert_string,
+ param_insert_float, param_insert_real, param_insert_double,
+ param_insert_mix, param_update, param_delete, param_select].
+
+%%-------------------------------------------------------------------------
+param_integers(doc)->
+ ["Test insertion of integers by parameterized queries."];
+param_integers(suite) ->
+ [param_insert_tiny_int,
+ param_insert_small_int, param_insert_int, param_insert_integer].
+%%-------------------------------------------------------------------------
+param_insert_tiny_int(doc)->
+ ["Test insertion of tiny ints by parameterized queries."];
+param_insert_tiny_int(suite) ->
+ [];
+param_insert_tiny_int(Config) when is_list(Config) ->
+ case ?RDBMS of
+ sqlserver ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD TINYINT)"),
+
+ {updated, Count} =
+ odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_tinyint, [1, 2]}],
+ ?TIMEOUT),%Make sure to test timeout clause
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ InsertResult = ?RDBMS:param_select_tiny_int(),
+
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_tinyint, [1, "2"]}])),
+ ok;
+ _ ->
+ {skip, "Type tiniyint not supported"}
+ end.
+%%-------------------------------------------------------------------------
+param_insert_small_int(doc)->
+ ["Test insertion of small ints by parameterized queries."];
+param_insert_small_int(suite) ->
+ [];
+param_insert_small_int(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD SMALLINT)"),
+
+ {updated, Count} =
+ odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)", [{sql_smallint, [1, 2]}],
+ ?TIMEOUT), %% Make sure to test timeout clause
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ InsertResult = ?RDBMS:param_select_small_int(),
+
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_smallint, [1, "2"]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_int(doc)->
+ ["Test insertion of ints by parameterized queries."];
+param_insert_int(suite) ->
+ [];
+param_insert_int(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD INT)"),
+
+ Int = ?RDBMS:small_int_max() + 1,
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_integer, [1, Int]}]),
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ InsertResult = ?RDBMS:param_select_int(),
+
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_integer, [1, "2"]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_integer(doc)->
+ ["Test insertion of integers by parameterized queries."];
+param_insert_integer(suite) ->
+ [];
+param_insert_integer(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD INTEGER)"),
+
+ Int = ?RDBMS:small_int_max() + 1,
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_integer, [1, Int]}]),
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ InsertResult = ?RDBMS:param_select_int(),
+
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_integer, [1, 2.3]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_decimal(doc)->
+ ["Test insertion of decimal numbers by parameterized queries."];
+param_insert_decimal(suite) ->
+ [];
+param_insert_decimal(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD DECIMAL (3,0))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_decimal, 3, 0}, [1, 2]}]),
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ InsertResult = ?RDBMS:param_select_decimal(),
+
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_decimal, 3, 0}, [1, "2"]}])),
+
+
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD DECIMAL (3,1))"),
+
+ {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_decimal, 3, 1}, [0.25]}]),
+ true = odbc_test_lib:check_row_count(1, NewCount),
+
+ {selected, Fields, [{Value}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fields),
+
+ odbc_test_lib:match_float(Value, 0.3, 0.01),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_numeric(doc)->
+ ["Test insertion of numeric numbers by parameterized queries."];
+param_insert_numeric(suite) ->
+ [];
+param_insert_numeric(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD NUMERIC (3,0))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_numeric,3,0}, [1, 2]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ InsertResult = ?RDBMS:param_select_numeric(),
+
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_decimal, 3, 0}, [1, "2"]}])),
+
+ odbc:sql_query(Ref, "DROP TABLE " ++ Table),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD NUMERIC (3,1))"),
+
+ {updated, NewCount} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_numeric, 3, 1}, [0.25]}]),
+
+ true = odbc_test_lib:check_row_count(1, NewCount),
+
+ {selected, Fileds, [{Value}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ odbc_test_lib:match_float(Value, 0.3, 0.01),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_string(doc) ->
+ ["Test insertion of strings by parameterized queries."];
+param_insert_string(suite) ->
+ [param_insert_char, param_insert_character, param_insert_char_varying,
+ param_insert_character_varying].
+
+%%-------------------------------------------------------------------------
+param_insert_char(doc)->
+ ["Test insertion of fixed length string by parameterized queries."];
+param_insert_char(suite) ->
+ [];
+param_insert_char(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD CHAR (10))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_char, 10},
+ ["foofoofoof", "0123456789"]}]),
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ {selected,Fileds,[{"foofoofoof"}, {"0123456789"}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_char, 10},
+ ["foo", "01234567890"]}]),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_char, 10}, ["1", 2.3]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_character(doc)->
+ ["Test insertion of fixed length string by parameterized queries."];
+param_insert_character(suite) ->
+ [];
+param_insert_character(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD CHARACTER (10))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_char, 10},
+ ["foofoofoof", "0123456789"]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ {selected, Fileds, [{"foofoofoof"}, {"0123456789"}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_char, 10},
+ ["foo", "01234567890"]}]),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_char, 10}, ["1", 2]}])),
+ ok.
+
+%%------------------------------------------------------------------------
+param_insert_char_varying(doc)->
+ ["Test insertion of variable length strings by parameterized queries."];
+param_insert_char_varying(suite) ->
+ [];
+param_insert_char_varying(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD CHAR VARYING(10))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_varchar, 10},
+ ["foo", "0123456789"]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ {selected, Fileds, [{"foo"}, {"0123456789"}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_varchar, 10},
+ ["foo", "01234567890"]}]),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_varchar, 10}, ["1", 2.3]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_character_varying(doc)->
+ ["Test insertion of variable length strings by parameterized queries."];
+param_insert_character_varying(suite) ->
+ [];
+param_insert_character_varying(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD CHARACTER VARYING(10))"),
+
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_varchar, 10},
+ ["foo", "0123456789"]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ {selected, Fileds, [{"foo"}, {"0123456789"}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ {error, _} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_varchar, 10},
+ ["foo", "01234567890"]}]),
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_varchar, 10}, ["1", 2]}])),
+ ok.
+%%-------------------------------------------------------------------------
+param_insert_float(doc)->
+ ["Test insertion of floats by parameterized queries."];
+param_insert_float(suite) ->
+ [];
+param_insert_float(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD FLOAT(5))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_float,5}, [1.3, 1.2]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ {selected, Fileds, [{Float1},{Float2}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ case (odbc_test_lib:match_float(Float1, 1.3, 0.000001) and
+ odbc_test_lib:match_float(Float2, 1.2, 0.000001)) of
+ true ->
+ ok;
+ false ->
+ test_server:fail(float_numbers_do_not_match)
+ end,
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{{sql_float, 5}, [1.0, "2"]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_real(doc)->
+ ["Test insertion of real numbers by parameterized queries."];
+param_insert_real(suite) ->
+ [];
+param_insert_real(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD REAL)"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_real, [1.3, 1.2]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ %_InsertResult = ?RDBMS:param_select_real(),
+
+ {selected, Fileds, [{Real1},{Real2}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ case (odbc_test_lib:match_float(Real1, 1.3, 0.000001) and
+ odbc_test_lib:match_float(Real2, 1.2, 0.000001)) of
+ true ->
+ ok;
+ false ->
+ test_server:fail(real_numbers_do_not_match)
+ end,
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_real,[1.0, "2"]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_double(doc)->
+ ["Test insertion of doubles by parameterized queries."];
+param_insert_double(suite) ->
+ [];
+param_insert_double(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (FIELD DOUBLE PRECISION)"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_double, [1.3, 1.2]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ {selected, Fileds, [{Double1},{Double2}]} =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+
+ ["FIELD"] = odbc_test_lib:to_upper(Fileds),
+
+ case (odbc_test_lib:match_float(Double1, 1.3, 0.000001) and
+ odbc_test_lib:match_float(Double2, 1.2, 0.000001)) of
+ true ->
+ ok;
+ false ->
+ test_server:fail(double_numbers_do_not_match)
+ end,
+
+ {'EXIT',{badarg,odbc,param_query,'Params'}} =
+ (catch odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(FIELD) VALUES(?)",
+ [{sql_double, [1.0, "2"]}])),
+ ok.
+
+%%-------------------------------------------------------------------------
+param_insert_mix(doc)->
+ ["Test insertion of a mixture of datatypes by parameterized queries."];
+param_insert_mix(suite) ->
+ [];
+param_insert_mix(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID INTEGER, DATA CHARACTER VARYING(10),"
+ " PRIMARY KEY(ID))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(ID, DATA) VALUES(?, ?)",
+ [{sql_integer, [1, 2]},
+ {{sql_varchar, 10}, ["foo", "bar"]}]),
+
+ true = odbc_test_lib:check_row_count(2, Count),
+
+ InsertResult = ?RDBMS:param_select_mix(),
+
+ InsertResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+ ok.
+%%-------------------------------------------------------------------------
+param_update(doc)->
+ ["Test parameterized update query."];
+param_update(suite) ->
+ [];
+param_update(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID INTEGER, DATA CHARACTER VARYING(10),"
+ " PRIMARY KEY(ID))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(ID, DATA) VALUES(?, ?)",
+ [{sql_integer, [1, 2, 3]},
+ {{sql_varchar, 10},
+ ["foo", "bar", "baz"]}]),
+
+ true = odbc_test_lib:check_row_count(3, Count),
+
+ {updated, NewCount} = odbc:param_query(Ref, "UPDATE " ++ Table ++
+ " SET DATA = 'foobar' WHERE ID = ?",
+ [{sql_integer, [1, 2]}]),
+
+ true = odbc_test_lib:check_row_count(2, NewCount),
+
+ UpdateResult = ?RDBMS:param_update(),
+
+ UpdateResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+ ok.
+
+%%-------------------------------------------------------------------------
+delete_nonexisting_row(doc) -> % OTP-5759
+ ["Make a delete...where with false conditions (0 rows deleted). ",
+ "This used to give an error message (see ticket OTP-5759)."];
+delete_nonexisting_row(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table
+ ++ " (ID INTEGER, DATA CHARACTER VARYING(10))"),
+ {updated, Count} =
+ odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(ID, DATA) VALUES(?, ?)",
+ [{sql_integer, [1, 2, 3]},
+ {{sql_varchar, 10}, ["foo", "bar", "baz"]}]),
+
+ true = odbc_test_lib:check_row_count(3, Count),
+
+ {updated, NewCount} =
+ odbc:sql_query(Ref, "DELETE FROM " ++ Table ++ " WHERE ID = 8"),
+
+ true = odbc_test_lib:check_row_count(0, NewCount),
+
+ {updated, _} =
+ odbc:sql_query(Ref, "DROP TABLE "++ Table),
+
+ ok.
+
+%%-------------------------------------------------------------------------
+param_delete(doc) ->
+ ["Test parameterized delete query."];
+param_delete(suite) ->
+ [];
+param_delete(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID INTEGER, DATA CHARACTER VARYING(10),"
+ " PRIMARY KEY(ID))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(ID, DATA) VALUES(?, ?)",
+ [{sql_integer, [1, 2, 3]},
+ {{sql_varchar, 10},
+ ["foo", "bar", "baz"]}]),
+ true = odbc_test_lib:check_row_count(3, Count),
+
+ {updated, NewCount} = odbc:param_query(Ref, "DELETE FROM " ++ Table ++
+ " WHERE ID = ?",
+ [{sql_integer, [1, 2]}]),
+
+ true = odbc_test_lib:check_row_count(2, NewCount),
+
+ UpdateResult = ?RDBMS:param_delete(),
+
+ UpdateResult =
+ odbc:sql_query(Ref, "SELECT * FROM " ++ Table),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+param_select(doc) ->
+ ["Test parameterized select query."];
+param_select(suite) ->
+ [];
+param_select(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (ID INTEGER, DATA CHARACTER VARYING(10),"
+ " PRIMARY KEY(ID))"),
+
+ {updated, Count} = odbc:param_query(Ref, "INSERT INTO " ++ Table ++
+ "(ID, DATA) VALUES(?, ?)",
+ [{sql_integer, [1, 2, 3]},
+ {{sql_varchar, 10},
+ ["foo", "bar", "foo"]}]),
+
+ true = odbc_test_lib:check_row_count(3, Count),
+
+ SelectResult = ?RDBMS:param_select(),
+
+ SelectResult = odbc:param_query(Ref, "SELECT * FROM " ++ Table ++
+ " WHERE DATA = ?",
+ [{{sql_varchar, 10}, ["foo"]}]),
+ ok.
+
+%%-------------------------------------------------------------------------
+describe_table(doc) ->
+ ["Test describe_table/[2,3]"];
+describe_table(suite) ->
+ [describe_integer, describe_string, describe_floating, describe_dec_num,
+ describe_no_such_table].
+
+%%-------------------------------------------------------------------------
+describe_integer(doc) ->
+ ["Test describe_table/[2,3] for integer columns."];
+describe_integer(suite) ->
+ [];
+describe_integer(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (int1 SMALLINT, int2 INT, int3 INTEGER)"),
+
+ Decs = ?RDBMS:describe_integer(),
+ %% Make sure to test timeout clause
+ Decs = odbc:describe_table(Ref, Table, ?TIMEOUT),
+ ok.
+
+%%-------------------------------------------------------------------------
+describe_string(doc) ->
+ ["Test describe_table/[2,3] for string columns."];
+describe_string(suite) ->
+ [];
+describe_string(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (str1 char(10), str2 character(10), "
+ "str3 CHAR VARYING(10), str4 "
+ "CHARACTER VARYING(10))"),
+
+ Decs = ?RDBMS:describe_string(),
+
+ Decs = odbc:describe_table(Ref, Table),
+ ok.
+
+%%-------------------------------------------------------------------------
+describe_floating(doc) ->
+ ["Test describe_table/[2,3] for floting columns."];
+describe_floating(suite) ->
+ [];
+describe_floating(Config) when is_list(Config) ->
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (f FLOAT(5), r REAL, "
+ "d DOUBLE PRECISION)"),
+
+ Decs = ?RDBMS:describe_floating(),
+
+ Decs = odbc:describe_table(Ref, Table),
+ ok.
+
+%%-------------------------------------------------------------------------
+describe_dec_num(doc) ->
+ ["Test describe_table/[2,3] for decimal and numerical columns"];
+describe_dec_num(suite) ->
+ [];
+describe_dec_num(Config) when is_list(Config) ->
+
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} =
+ odbc:sql_query(Ref,
+ "CREATE TABLE " ++ Table ++
+ " (dec DECIMAL(9,3), num NUMERIC(9,2))"),
+
+ Decs = ?RDBMS:describe_dec_num(),
+
+ Decs = odbc:describe_table(Ref, Table),
+ ok.
+
+
+%%-------------------------------------------------------------------------
+describe_timestamp(doc) ->
+ ["Test describe_table/[2,3] for tinmestap columns"];
+describe_timestamp(suite) ->
+ [];
+describe_timestamp(Config) when is_list(Config) ->
+
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {updated, _} = % Value == 0 || -1 driver dependent!
+ odbc:sql_query(Ref, "CREATE TABLE " ++ Table ++
+ ?RDBMS:create_timestamp_table()),
+
+ Decs = ?RDBMS:describe_timestamp(),
+
+ Decs = odbc:describe_table(Ref, Table),
+ ok.
+
+%%-------------------------------------------------------------------------
+describe_no_such_table(doc) ->
+ ["Test what happens if you try to describe a table that does not exist."];
+describe_no_such_table(suite) ->
+ [];
+describe_no_such_table(Config) when is_list(Config) ->
+
+ Ref = ?config(connection_ref, Config),
+ Table = ?config(tableName, Config),
+
+ {error, _ } = odbc:describe_table(Ref, Table),
+ ok.
+
+%%-------------------------------------------------------------------------
+%% Internal functions
+%%-------------------------------------------------------------------------
+
+is_driver_error(Error) ->
+ case is_list(Error) of
+ true ->
+ test_server:format("Driver error ~p~n", [Error]),
+ ok;
+ false ->
+ test_server:fail(Error)
+ end.
diff --git a/lib/odbc/test/odbc_start_SUITE.erl b/lib/odbc/test/odbc_start_SUITE.erl
new file mode 100644
index 0000000000..2cca8e4546
--- /dev/null
+++ b/lib/odbc/test/odbc_start_SUITE.erl
@@ -0,0 +1,147 @@
+%%
+%% %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(odbc_start_SUITE).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("test_server.hrl").
+-include("test_server_line.hrl").
+-include("odbc_test.hrl").
+
+%% 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 code:which(odbc) of
+ non_existing ->
+ {skip, "No ODBC built"};
+ _ ->
+ [{tableName, odbc_test_lib:unique_table_name()} | 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) ->
+ ok.
+%%--------------------------------------------------------------------
+%% 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) ->
+ test_server:format("ODBCINI = ~p~n", [os:getenv("ODBCINI")]),
+ 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 start/stop of odbc"];
+
+all(suite) ->
+ case odbc_test_lib:odbc_check() of
+ ok -> all();
+ Other -> {skip, Other}
+ end.
+
+all() ->
+ [start].
+
+
+%% Test cases starts here.
+%%--------------------------------------------------------------------
+
+start(doc) ->
+ ["Test start/stop of odbc"];
+start(suite) ->
+ [];
+start(Config) when is_list(Config) ->
+ {error,odbc_not_started} = odbc:connect(?RDBMS:connection_string(), []),
+ odbc:start(),
+ case odbc:connect(?RDBMS:connection_string(), []) of
+ {ok, Ref0} ->
+ ok = odbc:disconnect(Ref0),
+ odbc:stop(),
+ {error,odbc_not_started} =
+ odbc:connect(?RDBMS:connection_string(), []),
+ start_odbc(transient),
+ start_odbc(permanent);
+ {error, odbc_not_started} ->
+ test_server:fail(start_failed);
+ Error ->
+ test_server:format("Connection failed: ~p~n", [Error]),
+ {skip, "ODBC is not properly setup"}
+ end.
+
+start_odbc(Type) ->
+ ok = odbc:start(Type),
+ case odbc:connect(?RDBMS:connection_string(), []) of
+ {ok, Ref} ->
+ ok = odbc:disconnect(Ref),
+ odbc:stop();
+ {error, odbc_not_started} ->
+ test_server:fail(start_failed)
+ end.
diff --git a/lib/odbc/test/odbc_test.hrl b/lib/odbc/test/odbc_test.hrl
new file mode 100644
index 0000000000..87f50043db
--- /dev/null
+++ b/lib/odbc/test/odbc_test.hrl
@@ -0,0 +1,37 @@
+%%
+%% %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%
+%%
+
+
+% Default timetrap timeout (set in init_per_testcase).
+% This should be set relatively high (10-15 times the expected
+% max testcasetime).
+-define(default_timeout, ?t:minutes(10)).
+
+-define(RDBMS, case os:type() of
+ {unix, sunos} ->
+ postgres;
+ {unix,linux} ->
+ postgres;
+ {win32, _} ->
+ sqlserver
+ end).
+
+-define(TIMEOUT, 100000).
+
+
diff --git a/lib/odbc/test/odbc_test_lib.erl b/lib/odbc/test/odbc_test_lib.erl
new file mode 100644
index 0000000000..92e895eb87
--- /dev/null
+++ b/lib/odbc/test/odbc_test_lib.erl
@@ -0,0 +1,77 @@
+%%
+%% %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(odbc_test_lib).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+-include("odbc_test.hrl").
+-include("test_server.hrl").
+
+unique_table_name() ->
+ lists:reverse(lists:foldl(fun($@, Acc) -> [$t, $A |Acc] ;
+ (X, Acc) -> [X |Acc] end,
+ [], atom_to_list(node()))).
+
+match_float(Float, Match, Delta) ->
+ (Float < Match + Delta) and (Float > Match - Delta).
+
+odbc_check() ->
+ case erlang:system_info(wordsize) of
+ 4 ->
+ case test_server:os_type() of
+ {unix, sunos} ->
+ ok;
+ {unix, linux} ->
+ ok;
+ {win32, _} ->
+ ok;
+ Other ->
+ lists:flatten(
+ io_lib:format("Platform not supported: ~w",
+ [Other]))
+ end;
+ Other ->
+ case test_server:os_type() of
+ {unix, linux} ->
+ ok;
+ Platform ->
+ lists:flatten(
+ io_lib:format("Word on platform ~w size"
+ " ~w not supported", [Other,
+ Platform]))
+ end
+ end.
+
+check_row_count(Count, Count) ->
+ test_server:format("Correct row count Count: ~p~n", [Count]),
+ true;
+check_row_count(_, undefined) ->
+ test_server:format("Undefined row count ~n", []),
+ true;
+check_row_count(Expected, Count) ->
+ test_server:format("Incorrect row count Expected ~p Got ~p~n",
+ [Expected, Count]),
+ false.
+
+to_upper(List) ->
+ lists:map(fun(Str) -> string:to_upper(Str) end, List).
diff --git a/lib/odbc/test/oracle.erl b/lib/odbc/test/oracle.erl
new file mode 100644
index 0000000000..ebf6dbb6bf
--- /dev/null
+++ b/lib/odbc/test/oracle.erl
@@ -0,0 +1,246 @@
+%%
+%% %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(oracle).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+%-------------------------------------------------------------------------
+connection_string() ->
+ "DSN=Oracle8;UID=odbctest".
+
+%-------------------------------------------------------------------------
+insert_result() ->
+ {selected,["ID","DATA"],[{"1","bar"}]}.
+
+update_result() ->
+ {selected,["ID","DATA"],[{"1","foo"}]}.
+
+selected_ID(N, next) ->
+ {selected,["ID"],[{integer_to_list(N)}]};
+
+selected_ID(_, _) ->
+ {error, driver_does_not_support_function}.
+
+selected_next_N(1)->
+ {selected,["ID"],
+ [{"1"},
+ {"2"},
+ {"3"}]};
+
+selected_next_N(2)->
+ {selected,["ID"],
+ [{"4"},
+ {"5"}]}.
+
+selected_relative_N(_)->
+ {error, driver_does_not_support_function}.
+
+selected_absolute_N(_)->
+ {error, driver_does_not_support_function}.
+
+selected_list_rows() ->
+ {selected,["ID", "DATA"],[["1", "bar"],["2","foo"]]}.
+
+first_list_rows() ->
+ {error, driver_does_not_support_function}.
+last_list_rows() ->
+ {error, driver_does_not_support_function}.
+prev_list_rows() ->
+ {error, driver_does_not_support_function}.
+next_list_rows() ->
+ {selected,["ID","DATA"],[["1","bar"]]}.
+
+%% In case we get a better oracle driver that support this some day .....
+multiple_select()->
+ [{selected,["ID", "DATA"],[{"1", "bar"},{"2", "foo"}]},
+ {selected,["ID"],[{"foo"}]}].
+
+multiple_mix()->
+ [{updated, 1},{updated, 1},
+ {selected,["ID", "DATA"],[{"1", "foobar"},{"2", "foo"}]},
+ {updated, 1}, {selected,["DATA"],[{"foo"}]}].
+
+%-------------------------------------------------------------------------
+fixed_char_min() ->
+ 1.
+fixed_char_max() ->
+ 2000. %% Should be 255 acording to manual but empirical tests say 2000
+
+create_fixed_char_table(Size) ->
+ " (FIELD char(" ++ integer_to_list(Size) ++ "))".
+
+%-------------------------------------------------------------------------
+var_char_min() ->
+ 1.
+var_char_max() ->
+ 2000.
+
+create_var_char_table(Size) ->
+ " (FIELD varchar2(" ++ integer_to_list(Size) ++ "))".
+
+%-------------------------------------------------------------------------
+text_min() ->
+ 1.
+text_max() ->
+ 2147483646. % 2147483647. %% 2^31 - 1
+
+create_text_table() ->
+ " (FIELD long)". %Oracle long is variable length char data
+
+%-------------------------------------------------------------------------
+create_unicode_table() ->
+ " (FIELD nvarchar(50))".
+
+%-------------------------------------------------------------------------
+create_timestamp_table() ->
+ " (FIELD DATETIME)".
+
+%-------------------------------------------------------------------------
+tiny_int_min() ->
+ -999.
+tiny_int_max() ->
+ 999.
+
+create_tiny_int_table() ->
+ " (FIELD number(3, 0))".
+
+tiny_int_min_selected() ->
+ {selected,["FIELD"],[{-999}]}.
+
+tiny_int_max_selected() ->
+ {selected,["FIELD"], [{999}]}.
+
+%-------------------------------------------------------------------------
+small_int_min() ->
+ -99999.
+small_int_max() ->
+ 99999.
+
+create_small_int_table() ->
+ " (FIELD number(5, 0))".
+
+small_int_min_selected() ->
+ {selected,["FIELD"],[{-99999}]}.
+
+small_int_max_selected() ->
+ {selected,["FIELD"], [{99999}]}.
+
+%-------------------------------------------------------------------------
+int_min() ->
+ -999999999.
+int_max() ->
+ 999999999.
+
+create_int_table() ->
+ " (FIELD number(9, 0))".
+
+int_min_selected() ->
+ {selected,["FIELD"],[{-999999999}]}.
+
+int_max_selected() ->
+ {selected,["FIELD"], [{999999999}]}.
+
+%-------------------------------------------------------------------------
+big_int_min() ->
+ -99999999999999999999999999999999999999.
+
+big_int_max() ->
+ 99999999999999999999999999999999999999.
+
+create_big_int_table() ->
+ " (FIELD number(38,0))".
+
+big_int_min_selected() ->
+ {selected,["FIELD"], [{"-99999999999999999999999999999999999999"}]}.
+
+big_int_max_selected() ->
+ {selected,["FIELD"], [{"99999999999999999999999999999999999999"}]}.
+
+%-------------------------------------------------------------------------
+float_min() ->
+ 1.40129846432481707e-45.
+
+float_max() ->
+ 3.40282346638528860e+38.
+
+create_float_table() ->
+ " (FIELD float(32))".
+
+float_underflow() ->
+ "'4.94065645841246544e-324'".
+float_overflow() ->
+ "'1.79769313486231570e+308'".
+
+float_zero_selected() ->
+ {selected,["FIELD"],[{0.00000e+0}]}.
+
+%-------------------------------------------------------------------------
+param_select_small_int() ->
+ {selected,["FIELD"],[{"1"}, {"2"}]}.
+
+param_select_int() ->
+ Int = small_int_max() + 1,
+ {selected,["FIELD"],[{"1"}, {integer_to_list(Int)}]}.
+
+param_select_decimal() ->
+ {selected,["FIELD"],[{1},{2}]}.
+
+param_select_numeric() ->
+ {selected,["FIELD"],[{1},{2}]}.
+
+param_select_float() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_real() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_double() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_mix() ->
+ {selected,["ID","DATA"],[{"1", "foo"}, {"2", "bar"}]}.
+
+param_update() ->
+ {selected,["ID","DATA"],[{"1", "foobar"}, {"2", "foobar"}, {"3", "baz"}]}.
+
+param_delete() ->
+ {selected,["ID","DATA"],[{"3", "baz"}]}.
+
+param_select() ->
+ {selected,["ID","DATA"],[{"1", "foo"},{"3", "foo"}]}.
+
+%-------------------------------------------------------------------------
+describe_integer() ->
+ {ok,[{"INT1",{sql_decimal,38,0}},{"INT2",{sql_decimal,38,0}},
+ {"INT3",{sql_decimal,38,0}}]}.
+
+describe_string() ->
+ {ok,[{"STR1",{sql_char,10}},
+ {"STR2",{sql_char,10}},
+ {"STR3",{sql_varchar,10}},
+ {"STR4",{sql_varchar,10}}]}.
+
+describe_floating() ->
+ {ok,[{"F",sql_double},{"R",sql_double},{"D",sql_double}]}.
+describe_dec_num() ->
+ {ok,[{"DEC",{sql_decimal,9,3}},{"NUM",{sql_decimal,9,2}}]}.
diff --git a/lib/odbc/test/postgres.erl b/lib/odbc/test/postgres.erl
new file mode 100644
index 0000000000..169ca26e43
--- /dev/null
+++ b/lib/odbc/test/postgres.erl
@@ -0,0 +1,294 @@
+%%
+%% %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(postgres).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+%-------------------------------------------------------------------------
+connection_string() ->
+ case test_server:os_type() of
+ {unix, sunos} ->
+ "DSN=Postgres;UID=odbctest";
+ {unix, linux} ->
+ Size = erlang:system_info(wordsize),
+ linux_dist_connection_string(Size)
+ end.
+
+linux_dist_connection_string(4) ->
+ case linux_dist() of
+ "ubuntu" ->
+ "DSN=PostgresLinuxUbuntu;UID=odbctest";
+ _ ->
+ "DSN=PostgresLinux;UID=odbctest"
+ end;
+
+linux_dist_connection_string(_) ->
+ "DSN=PostgresLinux64;UID=odbctest".
+
+linux_dist() ->
+ case file:read_file("/etc/issue") of
+ {ok, Binary} ->
+ [Dist | _ ] = string:tokens(binary_to_list(Binary), " "),
+ string:to_lower(Dist);
+ {error, _} ->
+ other
+ end.
+
+
+%-------------------------------------------------------------------------
+insert_result() ->
+ {selected,["id","data"],[{1,"bar"}]}.
+
+update_result() ->
+ {selected,["id","data"],[{1,"foo"}]}.
+
+selected_ID(N, next) ->
+ {selected,["id"],[{N}]};
+
+selected_ID(_, _) ->
+ {error, driver_does_not_support_function}.
+
+selected_next_N(1)->
+ {selected,["id"],
+ [{1},
+ {2},
+ {3}]};
+
+selected_next_N(2)->
+ {selected,["id"],
+ [{4},
+ {5}]}.
+
+selected_relative_N(_)->
+ {error, driver_does_not_support_function}.
+
+selected_absolute_N(_)->
+ {error, driver_does_not_support_function}.
+
+selected_list_rows() ->
+ {selected,["id", "data"],[[1, "bar"],[2,"foo"]]}.
+
+first_list_rows() ->
+ {error, driver_does_not_support_function}.
+last_list_rows() ->
+ {error, driver_does_not_support_function}.
+prev_list_rows() ->
+ {error, driver_does_not_support_function}.
+next_list_rows() ->
+ {selected,["id","data"],[[1,"bar"]]}.
+
+%% In case we get a better postgres driver that support this some day .....
+multiple_select()->
+ [{selected,["id", "data"],[{1, "bar"},{2, "foo"}]},
+ {selected,["id"],[{"foo"}]}].
+
+multiple_mix()->
+ [{updated, 1},{updated, 1},
+ {selected,["id", "data"],[{1, "foobar"},{2, "foo"}]},
+ {updated, 1}, {selected,["data"],[{"foo"}]}].
+
+%-------------------------------------------------------------------------
+fixed_char_min() ->
+ 1.
+fixed_char_max() ->
+ 2000.
+
+create_fixed_char_table(Size) ->
+ " (FIELD char(" ++ integer_to_list(Size) ++ "))".
+
+%-------------------------------------------------------------------------
+var_char_min() ->
+ 1.
+var_char_max() ->
+ 2000.
+
+create_var_char_table(Size) ->
+ " (FIELD varchar(" ++ integer_to_list(Size) ++ "))".
+
+%-------------------------------------------------------------------------
+text_min() ->
+ 1.
+text_max() ->
+ 2147483646. % 2147483647. %% 2^31 - 1
+
+create_text_table() ->
+ " (FIELD text)".
+
+%-------------------------------------------------------------------------
+create_unicode_table() ->
+ " (FIELD text)".
+
+%-------------------------------------------------------------------------
+create_timestamp_table() ->
+ " (FIELD TIMESTAMP)".
+
+%-------------------------------------------------------------------------
+small_int_min() ->
+ -32768.
+small_int_max() ->
+ 32767.
+
+create_small_int_table() ->
+ " (FIELD smallint)".
+
+small_int_min_selected() ->
+ {selected,["field"],[{-32768}]}.
+
+small_int_max_selected() ->
+ {selected,["field"], [{32767}]}.
+
+%-------------------------------------------------------------------------
+int_min() ->
+ -2147483648.
+int_max() ->
+ 2147483647.
+
+create_int_table() ->
+ " (FIELD int)".
+
+int_min_selected() ->
+ {selected,["field"],[{-2147483648}]}.
+
+int_max_selected() ->
+ {selected,["field"], [{2147483647}]}.
+
+%-------------------------------------------------------------------------
+big_int_min() ->
+ -9223372036854775808.
+
+big_int_max() ->
+ 9223372036854775807.
+
+create_big_int_table() ->
+ " (FIELD bigint )".
+
+big_int_min_selected() ->
+ {selected,["field"], [{"-9223372036854775808"}]}.
+
+big_int_max_selected() ->
+ {selected,["field"], [{"9223372036854775807"}]}.
+
+%-------------------------------------------------------------------------
+bit_false() ->
+ 0.
+bit_true() ->
+ 1.
+
+create_bit_table() ->
+ " (FIELD bit)".
+
+bit_false_selected() ->
+ {selected,["field"],[{"0"}]}.
+
+bit_true_selected() ->
+ {selected,["field"], [{"1"}]}.
+
+%-------------------------------------------------------------------------
+float_min() ->
+ 1.79e-307.
+float_max() ->
+ 1.79e+308.
+
+create_float_table() ->
+ " (FIELD float)".
+
+float_underflow() ->
+ "1.80e-308".
+float_overflow() ->
+ "1.80e+308".
+
+float_zero_selected() ->
+ {selected,["field"],[{0.00000e+0}]}.
+
+%-------------------------------------------------------------------------
+real_min() ->
+ -3.40e+38.
+real_max() ->
+ 3.40e+38.
+
+real_underflow() ->
+ "-3.41e+38".
+
+real_overflow() ->
+ "3.41e+38".
+
+create_real_table() ->
+ " (FIELD real)".
+
+real_zero_selected() ->
+ {selected,["field"],[{0.00000e+0}]}.
+
+%-------------------------------------------------------------------------
+param_select_small_int() ->
+ {selected,["field"],[{1}, {2}]}.
+
+param_select_int() ->
+ Int = small_int_max() + 1,
+ {selected,["field"],[{1}, {Int}]}.
+
+param_select_decimal() ->
+ {selected,["field"],[{1},{2}]}.
+
+param_select_numeric() ->
+ {selected,["field"],[{1},{2}]}.
+
+param_select_float() ->
+ {selected,["field"],[{1.30000},{1.20000}]}.
+
+param_select_real() ->
+ {selected,["field"],[{1.30000},{1.20000}]}.
+
+param_select_double() ->
+ {selected,["field"],[{1.30000},{1.20000}]}.
+
+param_select_mix() ->
+ {selected,["id","data"],[{1, "foo"}, {2, "bar"}]}.
+
+param_update() ->
+ {selected,["id","data"],[{3, "baz"},{1, "foobar"}, {2, "foobar"}]}.
+
+param_delete() ->
+ {selected,["id","data"],[{3, "baz"}]}.
+
+param_select() ->
+ {selected,["id","data"],[{1, "foo"},{3, "foo"}]}.
+
+%-------------------------------------------------------------------------
+describe_integer() ->
+ {ok,[{"int1",sql_smallint},
+ {"int2",sql_integer},
+ {"int3",sql_integer}]}.
+
+describe_string() ->
+ {ok,[{"str1",{sql_char,10}},
+ {"str2",{sql_char,10}},
+ {"str3",{sql_varchar,10}},
+ {"str4",{sql_varchar,10}}]}.
+
+describe_floating() ->
+ {ok,[{"f",sql_real},{"r",sql_real},{"d",{sql_float,15}}]}.
+describe_dec_num() ->
+ {ok,[{"dec",{sql_numeric,9,3}},{"num",{sql_numeric,9,2}}]}.
+
+describe_timestamp() ->
+ {ok, [{"field", sql_timestamp}]}.
diff --git a/lib/odbc/test/sqlserver.erl b/lib/odbc/test/sqlserver.erl
new file mode 100644
index 0000000000..e3fe30e0bc
--- /dev/null
+++ b/lib/odbc/test/sqlserver.erl
@@ -0,0 +1,298 @@
+%%
+%% %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(sqlserver).
+
+%% Note: This directive should only be used in test suites.
+-compile(export_all).
+
+%-------------------------------------------------------------------------
+connection_string() ->
+ "DSN=sql-server;UID=odbctest;PWD=gurka".
+
+%-------------------------------------------------------------------------
+insert_result() ->
+ {selected,["ID","DATA"],[{1,"bar"}]}.
+
+update_result() ->
+ {selected,["ID","DATA"],[{1,"foo"}]}.
+
+selected_ID(N, _) ->
+ {selected,["ID"],[{N}]}.
+
+selected_next_N(1)->
+ {selected,["ID"],
+ [{1},
+ {2},
+ {3}]};
+
+selected_next_N(2)->
+ {selected,["ID"],
+ [{4},
+ {5}]}.
+
+selected_relative_N(1)->
+ {selected,["ID"],
+ [{2},
+ {3},
+ {4}]};
+
+selected_relative_N(2)->
+ {selected,["ID"],
+ [{7},
+ {8}]}.
+
+selected_absolute_N(1)->
+ {selected,["ID"],
+ [{1},
+ {2},
+ {3}]};
+
+selected_absolute_N(2)->
+ {selected,["ID"],
+ [{1},
+ {2},
+ {3},
+ {4},
+ {5}]}.
+
+selected_list_rows() ->
+ {selected,["ID", "DATA"],[[1, "bar"],[2,"foo"]]}.
+
+first_list_rows() ->
+ {selected,["ID", "DATA"],[[1, "bar"]]}.
+last_list_rows() ->
+ {selected,["ID", "DATA"],[[2, "foo"]]}.
+prev_list_rows() ->
+ {selected,["ID", "DATA"],[[1, "bar"]]}.
+next_list_rows() ->
+ {selected,["ID", "DATA"],[[2, "foo"]]}.
+
+multiple_select()->
+ [{selected,["ID", "DATA"],[{1, "bar"},{2, "foo"}]},
+ {selected,["DATA"],[{"foo"}]}].
+
+multiple_mix()->
+ [{updated, 1},{updated, 1},
+ {selected,["ID", "DATA"],[{1, "foobar"},{2, "foo"}]},
+ {updated, 1}, {selected,["DATA"],[{"foo"}]}].
+
+%-------------------------------------------------------------------------
+fixed_char_min() ->
+ 1.
+
+fixed_char_max() ->
+ 8000.
+
+create_fixed_char_table(Size) ->
+ " (FIELD char(" ++ integer_to_list(Size) ++ "))".
+
+%-------------------------------------------------------------------------
+var_char_min() ->
+ 1.
+var_char_max() ->
+ 8000.
+
+create_var_char_table(Size) ->
+ " (FIELD varchar(" ++ integer_to_list(Size) ++ "))".
+%-------------------------------------------------------------------------
+text_min() ->
+ 1.
+text_max() ->
+ 2147483647. %% 2^31 - 1
+
+create_text_table() ->
+ " (FIELD text)".
+
+%-------------------------------------------------------------------------
+create_unicode_table() ->
+ " (FIELD nvarchar(50))".
+
+%-------------------------------------------------------------------------
+create_timestamp_table() ->
+ " (FIELD DATETIME)".
+
+%-------------------------------------------------------------------------
+tiny_int_min() ->
+ 0.
+tiny_int_max() ->
+ 255.
+
+create_tiny_int_table() ->
+ " (FIELD tinyint)".
+
+tiny_int_min_selected() ->
+ {selected,["FIELD"],[{tiny_int_min()}]}.
+
+tiny_int_max_selected() ->
+ {selected,["FIELD"], [{tiny_int_max()}]}.
+
+%-------------------------------------------------------------------------
+small_int_min() ->
+ -32768. % -2^15
+small_int_max() ->
+ 32767. % 2^15-1
+
+create_small_int_table() ->
+ " (FIELD smallint)".
+
+small_int_min_selected() ->
+ {selected,["FIELD"],[{small_int_min()}]}.
+
+small_int_max_selected() ->
+ {selected,["FIELD"], [{small_int_max()}]}.
+
+%-------------------------------------------------------------------------
+int_min() ->
+ -2147483648. % -2^31
+int_max() ->
+ 2147483647. % 2^31-1
+
+create_int_table() ->
+ " (FIELD int)".
+
+int_min_selected() ->
+ {selected,["FIELD"],[{int_min()}]}.
+
+int_max_selected() ->
+ {selected,["FIELD"], [{int_max()}]}.
+
+%-------------------------------------------------------------------------
+big_int_min() ->
+ -9223372036854775808. % -2^63
+big_int_max() ->
+ 9223372036854775807. % 2^63-1
+
+create_big_int_table() ->
+ " (FIELD bigint)".
+
+big_int_min_selected() ->
+ {selected,["FIELD"],[{integer_to_list(big_int_min())}]}.
+
+big_int_max_selected() ->
+ {selected,["FIELD"], [{integer_to_list(big_int_max())}]}.
+
+%-------------------------------------------------------------------------
+bit_false() ->
+ 0.
+bit_true() ->
+ 1.
+
+create_bit_table() ->
+ " (FIELD bit)".
+
+bit_false_selected() ->
+ {selected,["FIELD"],[{false}]}.
+
+bit_true_selected() ->
+ {selected,["FIELD"], [{true}]}.
+%-------------------------------------------------------------------------
+float_min() ->
+ -1.79e+308.
+float_max() ->
+ 1.79e+308.
+
+float_underflow() ->
+ "'-1.80e+308'".
+
+float_overflow() ->
+ "'-1.80e+308'".
+
+create_float_table() ->
+ " (FIELD float)".
+
+float_zero_selected() ->
+ {selected,["FIELD"],[{0.00000e+0}]}.
+%-------------------------------------------------------------------------
+real_min() ->
+ -3.40e+38.
+real_max() ->
+ 3.40e+38.
+
+real_underflow() ->
+ -3.41e+38.
+
+real_overflow() ->
+ 3.41e+38.
+
+create_real_table() ->
+ " (FIELD real)".
+
+real_zero_selected() ->
+ {selected,["FIELD"],[{0.00000e+0}]}.
+%-------------------------------------------------------------------------
+param_select_tiny_int() ->
+ {selected,["FIELD"],[{1}, {2}]}.
+
+param_select_small_int() ->
+ {selected,["FIELD"],[{1}, {2}]}.
+
+param_select_int() ->
+ Int = small_int_max() + 1,
+ {selected,["FIELD"],[{1}, {Int}]}.
+
+param_select_decimal() ->
+ {selected,["FIELD"],[{1},{2}]}.
+
+param_select_numeric() ->
+ {selected,["FIELD"],[{1},{2}]}.
+
+param_select_float() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_real() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_double() ->
+ {selected,["FIELD"],[{1.30000},{1.20000}]}.
+
+param_select_mix() ->
+ {selected,["ID","DATA"],[{1, "foo"}, {2, "bar"}]}.
+
+param_update() ->
+ {selected,["ID","DATA"],[{1, "foobar"}, {2, "foobar"}, {3, "baz"}]}.
+
+param_delete() ->
+ {selected,["ID","DATA"],[{3, "baz"}]}.
+
+param_select() ->
+ {selected,["ID","DATA"],[{1, "foo"},{3, "foo"}]}.
+
+%-------------------------------------------------------------------------
+
+describe_integer() ->
+ {ok,[{"int1", sql_smallint},{"int2", sql_integer},
+ {"int3", sql_integer}]}.
+
+describe_string() ->
+ {ok,[{"str1",{sql_char,10}},
+ {"str2",{sql_char,10}},
+ {"str3",{sql_varchar,10}},
+ {"str4",{sql_varchar,10}}]}.
+
+describe_floating() ->
+ {ok,[{"f", sql_real},{"r", sql_real}, {"d", {sql_float, 53}}]}.
+
+describe_dec_num() ->
+ {ok,[{"dec",{sql_decimal,9,3}},{"num",{sql_numeric,9,2}}]}.
+
+describe_timestamp() ->
+ {ok, [{"field", sql_timestamp}]}.
diff --git a/lib/parsetools/src/leex.erl b/lib/parsetools/src/leex.erl
index fd494eaf06..d0b4b9efe7 100644
--- a/lib/parsetools/src/leex.erl
+++ b/lib/parsetools/src/leex.erl
@@ -35,7 +35,7 @@
-export([compile/3,file/1,file/2,format_error/1]).
-import(lists, [member/2,reverse/1,sort/1,delete/2,
- keysearch/3,keysort/2,keydelete/3,keyfind/3,
+ keysort/2,keydelete/3,keyfind/3,
map/2,foldl/3,foreach/2,flatmap/2]).
-import(string, [substr/2,substr/3,span/2]).
-import(ordsets, [is_element/2,add_element/2,union/2]).
@@ -182,18 +182,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 =:= scannerfile ->
+ V = case lists:keyfind(Key, 1, Options) of
+ {Key, Filename0} when Key =:= includefile;
+ Key =:= scannerfile ->
case is_filename(Filename0) of
no ->
badarg;
Filename ->
{ok,[{Key,Filename}]}
end;
- {value,{Key,Bool}} when Bool; not Bool ->
- {ok,[{Key, Bool}]};
- {value,{Key, _}} ->
+ {Key, Bool} = KB when is_boolean(Bool) ->
+ {ok, [KB]};
+ {Key, _} ->
badarg;
false ->
{ok,[{Key,default_option(Key)}]}
@@ -231,8 +231,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.
@@ -320,10 +319,10 @@ filenames(File, Opts, St0) ->
St1 = St0#leex{xfile=Xfile,
opts=Opts,
module=Module},
- {value,{includefile,Ifile0}} = keysearch(includefile, 1, Opts),
+ {includefile,Ifile0} = lists:keyfind(includefile, 1, Opts),
Ifile = inc_file_name(Ifile0),
%% Test for explicit scanner file.
- {value,{scannerfile,Ofile}} = keysearch(scannerfile, 1, Opts),
+ {scannerfile,Ofile} = lists:keyfind(scannerfile, 1, Opts),
if
Ofile =:= [] ->
St1#leex{efile=filename:join(Dir, Efile),
@@ -495,7 +494,7 @@ parse_rule(S, Line, Atoks, Ms, N, St) ->
end.
var_used(Name, Toks) ->
- case keyfind(Name, 3, Toks) of
+ case lists:keyfind(Name, 3, Toks) of
{var,_,Name} -> true; %It's the var we want
_ -> false
end.
@@ -629,7 +628,7 @@ re_seq(Cs0, Sn0, St) ->
{Rs,Sn1,Cs1} -> {{seq,Rs},Sn1,Cs1}
end.
-re_seq1([C|_]=Cs0, Sn0, St) when C /= $|, C /= $) ->
+re_seq1([C|_]=Cs0, Sn0, St) when C =/= $|, C =/= $) ->
{L,Sn1,Cs1} = re_repeat(Cs0, Sn0, St),
{Rs,Sn2,Cs2} = re_seq1(Cs1, Sn1, St),
{[L|Rs],Sn2,Cs2};
@@ -751,9 +750,9 @@ re_char_class("[:" ++ Cs0, Cc, #leex{posix=true}=St) ->
{Pcl,":]" ++ Cs1} -> re_char_class(Cs1, [{posix,Pcl}|Cc], St);
{_,Cs1} -> parse_error({posix_cc,string_between(Cs0, Cs1)})
end;
-re_char_class([C1|Cs0], Cc, St) when C1 /= $] ->
+re_char_class([C1|Cs0], Cc, St) when C1 =/= $] ->
case re_char(C1, Cs0) of
- {Cf,[$-,C2|Cs1]} when C2 /= $] ->
+ {Cf,[$-,C2|Cs1]} when C2 =/= $] ->
case re_char(C2, Cs1) of
{Cl,Cs2} when Cf < Cl ->
re_char_class(Cs2, [{range,Cf,Cl}|Cc], St);
@@ -998,7 +997,7 @@ pack_crs([{C1,C2},{C3,C4}|Crs]) when C2 >= C3, C2 < C4 ->
%% C1 C2
%% C3 C4
pack_crs([{C1,C4}|Crs]);
-pack_crs([{C1,C2},{C3,C4}|Crs]) when C2 + 1 == C3 ->
+pack_crs([{C1,C2},{C3,C4}|Crs]) when C2 + 1 =:= C3 ->
%% C1 C2
%% C3 C4
pack_crs([{C1,C4}|Crs]);
@@ -1055,7 +1054,7 @@ build_dfa(Set, Us, N, Ts, Ms, NFA) ->
%% List of all transition sets.
Crs0 = [Cr || S <- Set,
{Crs,_St} <- (element(S, NFA))#nfa_state.edges,
- Crs /= epsilon, % Not an epsilon transition
+ Crs =/= epsilon, % Not an epsilon transition
Cr <- Crs ],
Crs1 = lists:usort(Crs0), % Must remove duplicates!
%% Build list of disjoint test ranges.
@@ -1072,7 +1071,7 @@ disjoint_crs([{_C1,C2}=Cr1,{C3,_C4}=Cr2|Crs]) when C2 < C3 ->
%% C1 C2
%% C3 C4
[Cr1|disjoint_crs([Cr2|Crs])];
-disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 == C3 ->
+disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 =:= C3 ->
%% C1 C2
%% C3 C4
[{C1,C2}|disjoint_crs(add_element({C2+1,C4}, Crs))];
@@ -1080,7 +1079,7 @@ disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 < C3, C2 >= C3, C2 < C4 ->
%% C1 C2
%% C3 C4
[{C1,C3-1}|disjoint_crs(union([{C3,C2},{C2+1,C4}], Crs))];
-disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 < C3, C2 == C4 ->
+disjoint_crs([{C1,C2},{C3,C4}|Crs]) when C1 < C3, C2 =:= C4 ->
%% C1 C2
%% C3 C4
[{C1,C3-1}|disjoint_crs(add_element({C3,C4}, Crs))];
@@ -1093,7 +1092,7 @@ disjoint_crs([]) -> [].
build_dfa([Cr|Crs], Set, Us, N, Ts, Ms, NFA) ->
case eclosure(move(Set, Cr, NFA), NFA) of
- S when S /= [] ->
+ S when S =/= [] ->
case dfa_state_exist(S, Us, Ms) of
{yes,T} ->
build_dfa(Crs, Set, Us, N, store(Cr, T, Ts), Ms, NFA);
@@ -1110,11 +1109,11 @@ build_dfa([], _, Us, N, Ts, _, _) ->
%% dfa_state_exist(Set, Unmarked, Marked) -> {yes,State} | no.
dfa_state_exist(S, Us, Ms) ->
- case keysearch(S, #dfa_state.nfa, Us) of
- {value,#dfa_state{no=T}} -> {yes,T};
+ case lists:keyfind(S, #dfa_state.nfa, Us) of
+ #dfa_state{no=T} -> {yes,T};
false ->
- case keysearch(S, #dfa_state.nfa, Ms) of
- {value,#dfa_state{no=T}} -> {yes,T};
+ case lists:keyfind(S, #dfa_state.nfa, Ms) of
+ #dfa_state{no=T} -> {yes,T};
false -> no
end
end.
@@ -1129,7 +1128,7 @@ eclosure(Sts, NFA) -> eclosure(Sts, NFA, []).
eclosure([St|Sts], NFA, Ec) ->
#nfa_state{edges=Es} = element(St, NFA),
eclosure([ N || {epsilon,N} <- Es,
- not is_element(N, Ec) ] ++ Sts,
+ not is_element(N, Ec) ] ++ Sts,
NFA, add_element(St, Ec));
eclosure([], _, Ec) -> Ec.
@@ -1137,7 +1136,7 @@ move(Sts, Cr, NFA) ->
%% io:fwrite("move1: ~p\n", [{Sts,Cr}]),
[ St || N <- Sts,
{Crs,St} <- (element(N, NFA))#nfa_state.edges,
- Crs /= epsilon, % Not an epsilon transition
+ Crs =/= epsilon, % Not an epsilon transition
in_crs(Cr, Crs) ].
in_crs({C1,C2}, [{C3,C4}|_Crs]) when C1 >= C3, C2 =< C4 -> true;
@@ -1436,7 +1435,7 @@ pack_trans([{{$\n,Cl},S}|Trs], Pt) ->
pack_trans([{{Cf,Cl},S}|Trs], Pt) when Cf < $\n, Cl > $\n ->
pack_trans([{{Cf,$\n-1},S},{{$\n+1,Cl},S}|Trs], [{$\n,S}|Pt]);
%% Small ranges become singletons.
-pack_trans([{{Cf,Cl},S}|Trs], Pt) when Cl == Cf + 1 ->
+pack_trans([{{Cf,Cl},S}|Trs], Pt) when Cl =:= Cf + 1 ->
pack_trans(Trs, [{Cf,S},{Cl,S}|Pt]);
pack_trans([Tr|Trs], Pt) -> % The default uninteresting case
pack_trans(Trs, Pt ++ [Tr]);
diff --git a/lib/public_key/asn1/OTP-PKIX.asn1 b/lib/public_key/asn1/OTP-PKIX.asn1
index 2bcacc0990..c0cf440496 100644
--- a/lib/public_key/asn1/OTP-PKIX.asn1
+++ b/lib/public_key/asn1/OTP-PKIX.asn1
@@ -313,7 +313,7 @@ SupportedPublicKeyAlgorithms PUBLIC-KEY-ALGORITHM-CLASS ::= {
dsa-with-sha1 SIGNATURE-ALGORITHM-CLASS ::= {
ID id-dsa-with-sha1
- TYPE NULL } -- XXX Must be empty and not NULL
+ TYPE Dss-Parms }
--
-- RSA Keys and Signatures
diff --git a/lib/public_key/src/pubkey_cert.erl b/lib/public_key/src/pubkey_cert.erl
index 8f7dfa8352..0651dcec29 100644
--- a/lib/public_key/src/pubkey_cert.erl
+++ b/lib/public_key/src/pubkey_cert.erl
@@ -29,7 +29,7 @@
validate_issuer/4, validate_names/6,
validate_revoked_status/3, validate_extensions/4,
validate_unknown_extensions/3,
- normalize_general_name/1, digest_type/1, digest/2, is_self_signed/1,
+ normalize_general_name/1, digest_type/1, is_self_signed/1,
is_issuer/2, issuer_id/2, is_fixed_dh_cert/1]).
-define(NULL, 0).
@@ -130,13 +130,14 @@ validate_signature(OtpCert, DerCert, Key, KeyParams,
validate_names(OtpCert, Permit, Exclude, Last, AccErr, Verify) ->
case is_self_signed(OtpCert) andalso (not Last) of
true ->
- ok;
+ AccErr;
false ->
TBSCert = OtpCert#'OTPCertificate'.tbsCertificate,
Subject = TBSCert#'OTPTBSCertificate'.subject,
+ Extensions =
+ extensions_list(TBSCert#'OTPTBSCertificate'.extensions),
AltSubject =
- select_extension(?'id-ce-subjectAltName',
- TBSCert#'OTPTBSCertificate'.extensions),
+ select_extension(?'id-ce-subjectAltName', Extensions),
EmailAddress = extract_email(Subject),
Name = [{directoryName, Subject}|EmailAddress],
@@ -196,7 +197,7 @@ normalize_general_name({rdnSequence, Issuer}) ->
normalize_general_name(Issuer) ->
Normalize = fun([{Description, Type, {printableString, Value}}]) ->
NewValue = string:to_lower(strip_spaces(Value)),
- {Description, Type, {printableString, NewValue}};
+ [{Description, Type, {printableString, NewValue}}];
(Atter) ->
Atter
end,
@@ -212,7 +213,7 @@ is_issuer({rdnSequence, Issuer}, {rdnSequence, Candidate}) ->
issuer_id(Otpcert, other) ->
TBSCert = Otpcert#'OTPCertificate'.tbsCertificate,
- Extensions = TBSCert#'OTPTBSCertificate'.extensions,
+ Extensions = extensions_list(TBSCert#'OTPTBSCertificate'.extensions),
case select_extension(?'id-ce-authorityKeyIdentifier', Extensions) of
undefined ->
{error, issuer_not_found};
@@ -232,12 +233,17 @@ is_fixed_dh_cert(#'OTPCertificate'{tbsCertificate =
SubjectPublicKeyInfo,
extensions =
Extensions}}) ->
- is_fixed_dh_cert(SubjectPublicKeyInfo, Extensions).
+ is_fixed_dh_cert(SubjectPublicKeyInfo, extensions_list(Extensions)).
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
+extensions_list(asn1_NOVALUE) ->
+ [];
+extensions_list(Extensions) ->
+ Extensions.
+
not_valid(Error, true, _) ->
throw(Error);
not_valid(Error, false, AccErrors) ->
@@ -269,13 +275,6 @@ digest_type(?md5WithRSAEncryption) ->
digest_type(?'id-dsa-with-sha1') ->
sha.
-digest(?sha1WithRSAEncryption, Msg) ->
- crypto:sha(Msg);
-digest(?md5WithRSAEncryption, Msg) ->
- crypto:md5(Msg);
-digest(?'id-dsa-with-sha1', Msg) ->
- crypto:sha(Msg).
-
public_key_info(PublicKeyInfo,
#path_validation_state{working_public_key_algorithm =
WorkingAlgorithm,
@@ -326,12 +325,6 @@ is_dir_name([[{'AttributeTypeAndValue', Type, What1}]|Rest1],
true -> is_dir_name(Rest1,Rest2,Exact);
false -> false
end;
-is_dir_name([{'AttributeTypeAndValue', Type, What1}|Rest1],
- [{'AttributeTypeAndValue', Type, What2}|Rest2], Exact) ->
- case is_dir_name2(What1,What2) of
- true -> is_dir_name(Rest1,Rest2,Exact);
- false -> false
- end;
is_dir_name(_,[],false) ->
true;
is_dir_name(_,_,_) ->
diff --git a/lib/public_key/src/pubkey_cert_records.erl b/lib/public_key/src/pubkey_cert_records.erl
index c7d4080adb..ac04e1c2cb 100644
--- a/lib/public_key/src/pubkey_cert_records.erl
+++ b/lib/public_key/src/pubkey_cert_records.erl
@@ -25,8 +25,6 @@
-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.
-
%%====================================================================
%% Internal application API
%%====================================================================
@@ -35,77 +33,25 @@ decode_cert(DerCert, plain) ->
'OTP-PUB-KEY':decode('Certificate', DerCert);
decode_cert(DerCert, otp) ->
{ok, Cert} = 'OTP-PUB-KEY':decode('OTPCertificate', DerCert),
- {ok, decode_all_otp(Cert)}.
-
-old_decode_cert(DerCert, otp) ->
- {ok, Cert} = 'OTP-PUB-KEY':decode('Certificate', DerCert),
- {ok, plain_to_otp(Cert)}.
-
-old_encode_cert(Cert) ->
- PlainCert = otp_to_plain(Cert),
- {ok, EncCert} = 'OTP-PUB-KEY':encode('Certificate', PlainCert),
- list_to_binary(EncCert).
-
+ #'OTPCertificate'{tbsCertificate = TBS} = Cert,
+ {ok, Cert#'OTPCertificate'{tbsCertificate = decode_tbs(TBS)}}.
encode_cert(Cert = #'Certificate'{}) ->
{ok, EncCert} = 'OTP-PUB-KEY':encode('Certificate', Cert),
list_to_binary(EncCert);
-encode_cert(C = #'OTPCertificate'{tbsCertificate = TBS =
- #'OTPTBSCertificate'{
- issuer=Issuer0,
- subject=Subject0,
- subjectPublicKeyInfo=Spki0,
- extensions=Exts0}
- }) ->
- Issuer = transform(Issuer0,encode),
- Subject = transform(Subject0,encode),
- Spki = encode_supportedPublicKey(Spki0),
- Exts = encode_extensions(Exts0),
- %% io:format("Extensions ~p~n",[Exts]),
- Cert = C#'OTPCertificate'{tbsCertificate=
- TBS#'OTPTBSCertificate'{
- issuer=Issuer, subject=Subject,
- subjectPublicKeyInfo=Spki,
- extensions=Exts}},
+encode_cert(C = #'OTPCertificate'{tbsCertificate = TBS}) ->
+ Cert = C#'OTPCertificate'{tbsCertificate=encode_tbs(TBS)},
{ok, EncCert} = 'OTP-PUB-KEY':encode('OTPCertificate', Cert),
list_to_binary(EncCert).
-encode_tbs_cert(TBS = #'OTPTBSCertificate'{
- issuer=Issuer0,
- subject=Subject0,
- subjectPublicKeyInfo=Spki0,
- extensions=Exts0}) ->
- Issuer = transform(Issuer0,encode),
- Subject = transform(Subject0,encode),
- Spki = encode_supportedPublicKey(Spki0),
- Exts = encode_extensions(Exts0),
- TBSCert = TBS#'OTPTBSCertificate'{issuer=Issuer,subject=Subject,
- subjectPublicKeyInfo=Spki,extensions=Exts},
- {ok, EncTBSCert} = 'OTP-PUB-KEY':encode('OTPTBSCertificate', TBSCert),
+encode_tbs_cert(TBS) ->
+ {ok, EncTBSCert} = 'OTP-PUB-KEY':encode('OTPTBSCertificate', encode_tbs(TBS)),
list_to_binary(EncTBSCert).
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-decode_all_otp(C = #'OTPCertificate'{tbsCertificate = TBS =
- #'OTPTBSCertificate'{
- issuer=Issuer0,
- subject=Subject0,
- subjectPublicKeyInfo=Spki0,
- extensions=Exts0}
- }) ->
- Issuer = transform(Issuer0,decode),
- Subject = transform(Subject0,decode),
- Spki = decode_supportedPublicKey(Spki0),
- Exts = decode_extensions(Exts0),
- %% io:format("Extensions ~p~n",[Exts]),
- C#'OTPCertificate'{tbsCertificate=
- TBS#'OTPTBSCertificate'{
- issuer=Issuer, subject=Subject,
- subjectPublicKeyInfo=Spki,extensions=Exts}}.
-
-
%%% SubjectPublicKey
supportedPublicKeyAlgorithms(?'rsaEncryption') -> 'RSAPublicKey';
supportedPublicKeyAlgorithms(?'id-dsa') -> 'DSAPublicKey';
@@ -204,15 +150,35 @@ transform({rdnSequence, SeqList},Func) when is_list(SeqList) ->
lists:map(fun(Seq) ->
lists:map(fun(Element) -> transform(Element,Func) end, Seq)
end, SeqList)};
-%% transform(List = [{rdnSequence, _}|_],Func) ->
-%% lists:map(fun(Element) -> transform(Element,Func) end, List);
transform(#'NameConstraints'{permittedSubtrees=Permitted, excludedSubtrees=Excluded}, Func) ->
- Res = #'NameConstraints'{permittedSubtrees=transform_sub_tree(Permitted,Func),
- excludedSubtrees=transform_sub_tree(Excluded,Func)},
-%% io:format("~p~n",[Res]),
- Res;
+ #'NameConstraints'{permittedSubtrees=transform_sub_tree(Permitted,Func),
+ excludedSubtrees=transform_sub_tree(Excluded,Func)};
+
transform(Other,_) ->
Other.
+
+encode_tbs(TBS=#'OTPTBSCertificate'{issuer=Issuer0,
+ subject=Subject0,
+ subjectPublicKeyInfo=Spki0,
+ extensions=Exts0}) ->
+ Issuer = transform(Issuer0,encode),
+ Subject = transform(Subject0,encode),
+ Spki = encode_supportedPublicKey(Spki0),
+ Exts = encode_extensions(Exts0),
+ TBS#'OTPTBSCertificate'{issuer=Issuer, subject=Subject,
+ subjectPublicKeyInfo=Spki,extensions=Exts}.
+
+decode_tbs(TBS = #'OTPTBSCertificate'{issuer=Issuer0,
+ subject=Subject0,
+ subjectPublicKeyInfo=Spki0,
+ extensions=Exts0}) ->
+ Issuer = transform(Issuer0,decode),
+ Subject = transform(Subject0,decode),
+ Spki = decode_supportedPublicKey(Spki0),
+ Exts = decode_extensions(Exts0),
+ TBS#'OTPTBSCertificate'{issuer=Issuer, subject=Subject,
+ subjectPublicKeyInfo=Spki,extensions=Exts}.
+
transform_sub_tree(asn1_NOVALUE,_) -> asn1_NOVALUE;
transform_sub_tree(TreeList,Func) ->
[Tree#'GeneralSubtree'{base=transform(Name,Func)} ||
@@ -236,303 +202,3 @@ attribute_type(?'id-at-pseudonym') -> 'X520Pseudonym';
attribute_type(?'id-domainComponent') -> 'DomainComponent';
attribute_type(?'id-emailAddress') -> 'EmailAddress';
attribute_type(Type) -> Type.
-
-%%% Old code transforms
-
-plain_to_otp(#'Certificate'{tbsCertificate = TBSCert,
- signatureAlgorithm = SigAlg,
- signature = Signature} = Cert) ->
- Cert#'Certificate'{tbsCertificate = plain_to_otp(TBSCert),
- signatureAlgorithm = plain_to_otp(SigAlg),
- signature = plain_to_otp(Signature)};
-
-plain_to_otp(#'TBSCertificate'{signature = Signature,
- issuer = Issuer,
- subject = Subject,
- subjectPublicKeyInfo = SPubKeyInfo,
- extensions = Extensions} = TBSCert) ->
-
- TBSCert#'TBSCertificate'{signature = plain_to_otp(Signature),
- issuer = plain_to_otp(Issuer),
- subject =
- plain_to_otp(Subject),
- subjectPublicKeyInfo =
- plain_to_otp(SPubKeyInfo),
- extensions =
- plain_to_otp_extensions(Extensions)
- };
-
-plain_to_otp(#'AlgorithmIdentifier'{algorithm = Algorithm,
- parameters = Params}) ->
- SignAlgAny =
- #'SignatureAlgorithm-Any'{algorithm = Algorithm,
- parameters = Params},
- {ok, AnyEnc} = 'OTP-PUB-KEY':encode('SignatureAlgorithm-Any',
- SignAlgAny),
- {ok, SignAlg} = 'OTP-PUB-KEY':decode('SignatureAlgorithm',
- list_to_binary(AnyEnc)),
- SignAlg;
-
-plain_to_otp({rdnSequence, SeqList}) when is_list(SeqList) ->
- {rdnSequence,
- lists:map(fun(Seq) ->
- lists:map(fun(Element) ->
- plain_to_otp(Element)
- end,
- Seq)
- end, SeqList)};
-
-plain_to_otp(#'AttributeTypeAndValue'{} = ATAV) ->
- {ok, ATAVEnc} =
- 'OTP-PUB-KEY':encode('AttributeTypeAndValue', ATAV),
- {ok, ATAVDec} = 'OTP-PUB-KEY':decode('OTPAttributeTypeAndValue',
- list_to_binary(ATAVEnc)),
- #'AttributeTypeAndValue'{type = ATAVDec#'OTPAttributeTypeAndValue'.type,
- value =
- ATAVDec#'OTPAttributeTypeAndValue'.value};
-
-plain_to_otp(#'SubjectPublicKeyInfo'{algorithm =
- #'AlgorithmIdentifier'{algorithm
- = Algo,
- parameters =
- Params},
- subjectPublicKey = PublicKey}) ->
-
- AnyAlgo = #'PublicKeyAlgorithm'{algorithm = Algo,
- parameters = Params},
- {0, AnyKey} = PublicKey,
- AnyDec = #'OTPSubjectPublicKeyInfo-Any'{algorithm = AnyAlgo,
- subjectPublicKey = AnyKey},
- {ok, AnyEnc} =
- 'OTP-PUB-KEY':encode('OTPSubjectPublicKeyInfo-Any', AnyDec),
- {ok, InfoDec} = 'OTP-PUB-KEY':decode('OTPOLDSubjectPublicKeyInfo',
- list_to_binary(AnyEnc)),
-
- AlgorithmDec = InfoDec#'OTPOLDSubjectPublicKeyInfo'.algorithm,
- AlgoDec = AlgorithmDec#'OTPOLDSubjectPublicKeyInfo_algorithm'.algo,
- NewParams = AlgorithmDec#'OTPOLDSubjectPublicKeyInfo_algorithm'.parameters,
- PublicKeyDec = InfoDec#'OTPOLDSubjectPublicKeyInfo'.subjectPublicKey,
- NewAlgorithmDec =
- #'SubjectPublicKeyInfoAlgorithm'{algorithm = AlgoDec,
- parameters = NewParams},
- #'SubjectPublicKeyInfo'{algorithm = NewAlgorithmDec,
- subjectPublicKey = PublicKeyDec
- };
-
-plain_to_otp(#'Extension'{extnID = ExtID,
- critical = Critical,
- extnValue = Value})
- when ExtID == ?'id-ce-authorityKeyIdentifier';
- ExtID == ?'id-ce-subjectKeyIdentifier';
- ExtID == ?'id-ce-keyUsage';
- ExtID == ?'id-ce-privateKeyUsagePeriod';
- ExtID == ?'id-ce-certificatePolicies';
- ExtID == ?'id-ce-policyMappings';
- ExtID == ?'id-ce-subjectAltName';
- ExtID == ?'id-ce-issuerAltName';
- ExtID == ?'id-ce-subjectDirectoryAttributes';
- ExtID == ?'id-ce-basicConstraints';
- ExtID == ?'id-ce-nameConstraints';
- ExtID == ?'id-ce-policyConstraints';
- ExtID == ?'id-ce-extKeyUsage';
- ExtID == ?'id-ce-cRLDistributionPoints';
- ExtID == ?'id-ce-inhibitAnyPolicy';
- ExtID == ?'id-ce-freshestCRL' ->
- ExtAny = #'Extension-Any'{extnID = ExtID,
- critical = Critical,
- extnValue = Value},
- {ok, AnyEnc} = 'OTP-PUB-KEY':encode('Extension-Any', ExtAny),
- {ok, ExtDec} = 'OTP-PUB-KEY':decode('OTPExtension',
- list_to_binary(AnyEnc)),
-
- ExtValue = plain_to_otp_extension_value(ExtID,
- ExtDec#'OTPExtension'.extnValue),
- #'Extension'{extnID = ExtID,
- critical = ExtDec#'OTPExtension'.critical,
- extnValue = ExtValue};
-
-plain_to_otp(#'Extension'{} = Ext) ->
- Ext;
-
-plain_to_otp(#'AuthorityKeyIdentifier'{} = Ext) ->
- CertIssuer = Ext#'AuthorityKeyIdentifier'.authorityCertIssuer,
- Ext#'AuthorityKeyIdentifier'{authorityCertIssuer =
- plain_to_otp(CertIssuer)};
-
-
-plain_to_otp([{directoryName, Value}]) ->
- [{directoryName, plain_to_otp(Value)}];
-
-plain_to_otp(Value) ->
- Value.
-
-otp_to_plain(#'Certificate'{tbsCertificate = TBSCert,
- signatureAlgorithm = SigAlg,
- signature = Signature} = Cert) ->
- Cert#'Certificate'{tbsCertificate = otp_to_plain(TBSCert),
- signatureAlgorithm =
- otp_to_plain(SigAlg),
- signature = otp_to_plain(Signature)};
-
-otp_to_plain(#'TBSCertificate'{signature = Signature,
- issuer = Issuer,
- subject = Subject,
- subjectPublicKeyInfo = SPubKeyInfo,
- extensions = Extensions} = TBSCert) ->
-
- TBSCert#'TBSCertificate'{signature = otp_to_plain(Signature),
- issuer = otp_to_plain(Issuer),
- subject =
- otp_to_plain(Subject),
- subjectPublicKeyInfo =
- otp_to_plain(SPubKeyInfo),
- extensions = otp_to_plain_extensions(Extensions)
- };
-
-otp_to_plain(#'SignatureAlgorithm'{} = SignAlg) ->
- {ok, EncSignAlg} = 'OTP-PUB-KEY':encode('SignatureAlgorithm', SignAlg),
- {ok, #'SignatureAlgorithm-Any'{algorithm = Algorithm,
- parameters = Params}} =
- 'OTP-PUB-KEY':decode('SignatureAlgorithm-Any',
- list_to_binary(EncSignAlg)),
- #'AlgorithmIdentifier'{algorithm = Algorithm,
- parameters = Params};
-
-otp_to_plain({rdnSequence, SeqList}) when is_list(SeqList) ->
- {rdnSequence,
- lists:map(fun(Seq) ->
- lists:map(fun(Element) ->
- otp_to_plain(Element)
- end,
- Seq)
- end, SeqList)};
-
-otp_to_plain(#'AttributeTypeAndValue'{type = Type, value = Value}) ->
- {ok, ATAVEnc} =
- 'OTP-PUB-KEY':encode('OTPAttributeTypeAndValue',
- #'OTPAttributeTypeAndValue'{type = Type,
- value = Value}),
- {ok, ATAVDec} = 'OTP-PUB-KEY':decode('AttributeTypeAndValue',
- list_to_binary(ATAVEnc)),
- ATAVDec;
-
-otp_to_plain(#'SubjectPublicKeyInfo'{algorithm =
- #'SubjectPublicKeyInfoAlgorithm'{
- algorithm = Algo,
- parameters =
- Params},
- subjectPublicKey = PublicKey}) ->
-
- OtpAlgo = #'OTPOLDSubjectPublicKeyInfo_algorithm'{algo = Algo,
- parameters = Params},
- OtpDec = #'OTPOLDSubjectPublicKeyInfo'{algorithm = OtpAlgo,
- subjectPublicKey = PublicKey},
- {ok, OtpEnc} =
- 'OTP-PUB-KEY':encode('OTPOLDSubjectPublicKeyInfo', OtpDec),
-
- {ok, AnyDec} = 'OTP-PUB-KEY':decode('OTPSubjectPublicKeyInfo-Any',
- list_to_binary(OtpEnc)),
-
- #'OTPSubjectPublicKeyInfo-Any'{algorithm = #'PublicKeyAlgorithm'{
- algorithm = NewAlgo,
- parameters = NewParams},
- subjectPublicKey = Bin} = AnyDec,
-
- #'SubjectPublicKeyInfo'{algorithm =
- #'AlgorithmIdentifier'{
- algorithm = NewAlgo,
- parameters = plain_key_params(NewParams)},
- subjectPublicKey =
- {0, Bin}
- };
-
-otp_to_plain(#'Extension'{extnID = ExtID,
- extnValue = Value} = Ext) ->
- ExtValue =
- otp_to_plain_extension_value(ExtID, Value),
-
- Ext#'Extension'{extnValue = ExtValue};
-
-otp_to_plain(#'AuthorityKeyIdentifier'{} = Ext) ->
- CertIssuer = Ext#'AuthorityKeyIdentifier'.authorityCertIssuer,
- Ext#'AuthorityKeyIdentifier'{authorityCertIssuer =
- otp_to_plain(CertIssuer)};
-
-otp_to_plain([{directoryName, Value}]) ->
- [{directoryName, otp_to_plain(Value)}];
-
-otp_to_plain(Value) ->
- Value.
-
-plain_key_params('NULL') ->
- <<5,0>>;
-plain_key_params(Value) ->
- Value.
-
-plain_to_otp_extension_value(?'id-ce-authorityKeyIdentifier', Value) ->
- plain_to_otp(Value);
-plain_to_otp_extension_value(_, Value) ->
- Value.
-
-plain_to_otp_extensions(Exts) when is_list(Exts) ->
- lists:map(fun(Ext) -> plain_to_otp(Ext) end, Exts).
-
-otp_to_plain_extension_value(?'id-ce-authorityKeyIdentifier', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('AuthorityKeyIdentifier',
- otp_to_plain(Value)),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-subjectKeyIdentifier', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('SubjectKeyIdentifier', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-keyUsage', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('KeyUsage', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-privateKeyUsagePeriod', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('PrivateKeyUsagePeriod', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-certificatePolicies', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('CertificatePolicies', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-policyMappings', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('PolicyMappings', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-subjectAltName', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('SubjectAltName', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-issuerAltName', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('IssuerAltName', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-subjectDirectoryAttributes', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('SubjectDirectoryAttributes', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-basicConstraints', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('BasicConstraints', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-nameConstraints', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('NameConstraints', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-policyConstraints', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('PolicyConstraints', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-extKeyUsage', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('ExtKeyUsage', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-cRLDistributionPoints', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('CRLDistributionPoints', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-inhibitAnyPolicy', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('InhibitAnyPolicy', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(?'id-ce-freshestCRL', Value) ->
- {ok, Enc} = 'OTP-PUB-KEY':encode('FreshestCRL', Value),
- otp_to_plain_extension_value_format(Enc);
-otp_to_plain_extension_value(_Id, Value) ->
- Value.
-
-otp_to_plain_extension_value_format(Value) ->
- list_to_binary(Value).
-
-otp_to_plain_extensions(Exts) when is_list(Exts) ->
- lists:map(fun(Ext) ->
- otp_to_plain(Ext)
- end, Exts).
diff --git a/lib/public_key/src/pubkey_pem.erl b/lib/public_key/src/pubkey_pem.erl
index 9fc17b6f73..65879f1bbe 100644
--- a/lib/public_key/src/pubkey_pem.erl
+++ b/lib/public_key/src/pubkey_pem.erl
@@ -124,25 +124,31 @@ decode_file2([L|Rest], RLs, Ens, Tag, Info0) ->
decode_file2([], _, Ens, _, _) ->
{ok, lists:reverse(Ens)}.
-%% TODO Support same as decode_file
+%% Support same as decode_file
encode_file(Ds) ->
lists:map(
- fun({cert, Bin}) ->
+ fun({cert, Bin, not_encrypted}) ->
%% PKIX (X.509)
["-----BEGIN CERTIFICATE-----\n",
b64encode_and_split(Bin),
"-----END CERTIFICATE-----\n\n"];
- ({cert_req, Bin}) ->
+ ({cert_req, Bin, not_encrypted}) ->
%% PKCS#10
["-----BEGIN CERTIFICATE REQUEST-----\n",
b64encode_and_split(Bin),
"-----END CERTIFICATE REQUEST-----\n\n"];
- ({rsa_private_key, Bin}) ->
+ ({rsa_private_key, Bin, not_encrypted}) ->
%% PKCS#?
["XXX Following key assumed not encrypted\n",
"-----BEGIN RSA PRIVATE KEY-----\n",
b64encode_and_split(Bin),
- "-----END RSA PRIVATE KEY-----\n\n"]
+ "-----END RSA PRIVATE KEY-----\n\n"];
+ ({dsa_private_key, Bin, not_encrypted}) ->
+ %% PKCS#?
+ ["XXX Following key assumed not encrypted\n",
+ "-----BEGIN DSA PRIVATE KEY-----\n",
+ b64encode_and_split(Bin),
+ "-----END DSA PRIVATE KEY-----\n\n"]
end, Ds).
dek_info(Line0, Info) ->
diff --git a/lib/public_key/src/public_key.erl b/lib/public_key/src/public_key.erl
index 157e76bb21..d1d45f21a0 100644
--- a/lib/public_key/src/public_key.erl
+++ b/lib/public_key/src/public_key.erl
@@ -113,13 +113,13 @@ decrypt_public(CipherText, Key, Options) ->
encrypt_public(PlainText, Key) ->
encrypt_public(PlainText, Key, []).
encrypt_public(PlainText, Key, Options) ->
- Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_oaep_padding),
+ Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding),
pubkey_crypto:encrypt_public(PlainText, Key, Padding).
encrypt_private(PlainText, Key) ->
encrypt_private(PlainText, Key, []).
encrypt_private(PlainText, Key, Options) ->
- Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_oaep_padding),
+ Padding = proplists:get_value(rsa_pad, Options, rsa_pkcs1_padding),
pubkey_crypto:encrypt_private(PlainText, Key, Padding).
%%--------------------------------------------------------------------
diff --git a/lib/public_key/test/Makefile b/lib/public_key/test/Makefile
index c7215020c7..5544339ff2 100644
--- a/lib/public_key/test/Makefile
+++ b/lib/public_key/test/Makefile
@@ -28,6 +28,7 @@ INCLUDES= -I. -I ../include
# ----------------------------------------------------
MODULES= \
+ pkey_test \
public_key_SUITE \
pkits_SUITE
@@ -40,6 +41,9 @@ TARGET_FILES= \
SPEC_FILES = public_key.spec
+COVER_FILE = public_key.cover
+
+
# ----------------------------------------------------
# Release directory specification
# ----------------------------------------------------
@@ -74,7 +78,7 @@ release_spec: opt
release_tests_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)
- $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(HRL_FILES)$(RELSYSDIR)
+ $(INSTALL_DATA) $(SPEC_FILES) $(ERL_FILES) $(COVER_FILE) $(HRL_FILES) $(RELSYSDIR)
$(INSTALL_DATA) $(TARGET_FILES) $(RELSYSDIR)
chmod -f -R u+w $(RELSYSDIR)
@tar cf - *_SUITE_data | (cd $(RELSYSDIR); tar xf -)
diff --git a/lib/public_key/test/pkey_test.erl b/lib/public_key/test/pkey_test.erl
new file mode 100644
index 0000000000..9d596eee4f
--- /dev/null
+++ b/lib/public_key/test/pkey_test.erl
@@ -0,0 +1,412 @@
+%%
+%% %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%
+%%
+
+%% Create test certificates
+
+-module(pkey_test).
+-include_lib("public_key/include/public_key.hrl").
+
+-export([make_cert/1, gen_rsa/1, verify_signature/3, write_pem/3]).
+-compile(export_all).
+
+%%--------------------------------------------------------------------
+%% @doc Create and return a der encoded certificate
+%% Option Default
+%% -------------------------------------------------------
+%% digest sha1
+%% validity {date(), date() + week()}
+%% version 3
+%% subject [] list of the following content
+%% {name, Name}
+%% {email, Email}
+%% {city, City}
+%% {state, State}
+%% {org, Org}
+%% {org_unit, OrgUnit}
+%% {country, Country}
+%% {serial, Serial}
+%% {title, Title}
+%% {dnQualifer, DnQ}
+%% issuer = {Issuer, IssuerKey} true (i.e. a ca cert is created)
+%% (obs IssuerKey migth be {Key, Password}
+%% key = KeyFile|KeyBin|rsa|dsa Subject PublicKey rsa or dsa generates key
+%%
+%%
+%% (OBS: The generated keys are for testing only)
+%% @spec ([{::atom(), ::term()}]) -> {Cert::binary(), Key::binary()}
+%% @end
+%%--------------------------------------------------------------------
+
+make_cert(Opts) ->
+ SubjectPrivateKey = get_key(Opts),
+ {TBSCert, IssuerKey} = make_tbs(SubjectPrivateKey, Opts),
+ Cert = public_key:sign(TBSCert, IssuerKey),
+ true = verify_signature(Cert, IssuerKey, undef), %% verify that the keys where ok
+ {Cert, encode_key(SubjectPrivateKey)}.
+
+%%--------------------------------------------------------------------
+%% @doc Writes pem files in Dir with FileName ++ ".pem" and FileName ++ "_key.pem"
+%% @spec (::string(), ::string(), {Cert,Key}) -> ok
+%% @end
+%%--------------------------------------------------------------------
+write_pem(Dir, FileName, {Cert, Key = {_,_,not_encrypted}}) when is_binary(Cert) ->
+ ok = public_key:der_to_pem(filename:join(Dir, FileName ++ ".pem"), [{cert, Cert, not_encrypted}]),
+ ok = public_key:der_to_pem(filename:join(Dir, FileName ++ "_key.pem"), [Key]).
+
+%%--------------------------------------------------------------------
+%% @doc Creates a rsa key (OBS: for testing only)
+%% the size are in bytes
+%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()}
+%% @end
+%%--------------------------------------------------------------------
+gen_rsa(Size) when is_integer(Size) ->
+ Key = gen_rsa2(Size),
+ {Key, encode_key(Key)}.
+
+%%--------------------------------------------------------------------
+%% @doc Creates a dsa key (OBS: for testing only)
+%% the sizes are in bytes
+%% @spec (::integer()) -> {::atom(), ::binary(), ::opaque()}
+%% @end
+%%--------------------------------------------------------------------
+gen_dsa(LSize,NSize) when is_integer(LSize), is_integer(NSize) ->
+ Key = gen_dsa2(LSize, NSize),
+ {Key, encode_key(Key)}.
+
+%%--------------------------------------------------------------------
+%% @doc Verifies cert signatures
+%% @spec (::binary(), ::tuple()) -> ::boolean()
+%% @end
+%%--------------------------------------------------------------------
+verify_signature(DerEncodedCert, DerKey, KeyParams) ->
+ Key = decode_key(DerKey),
+ case Key of
+ #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} ->
+ public_key:verify_signature(DerEncodedCert,
+ #'RSAPublicKey'{modulus=Mod, publicExponent=Exp},
+ 'NULL');
+ #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y} ->
+ public_key:verify_signature(DerEncodedCert, Y, #'Dss-Parms'{p=P, q=Q, g=G});
+
+ _ ->
+ public_key:verify_signature(DerEncodedCert, Key, KeyParams)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%% Implementation %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+get_key(Opts) ->
+ case proplists:get_value(key, Opts) of
+ undefined -> make_key(rsa, Opts);
+ rsa -> make_key(rsa, Opts);
+ dsa -> make_key(dsa, Opts);
+ Key ->
+ Password = proplists:get_value(password, Opts, no_passwd),
+ decode_key(Key, Password)
+ end.
+
+decode_key({Key, Pw}) ->
+ decode_key(Key, Pw);
+decode_key(Key) ->
+ decode_key(Key, no_passwd).
+
+
+decode_key(#'RSAPublicKey'{} = Key,_) ->
+ Key;
+decode_key(#'RSAPrivateKey'{} = Key,_) ->
+ Key;
+decode_key(#'DSAPrivateKey'{} = Key,_) ->
+ Key;
+decode_key(Der = {_,_,_}, Pw) ->
+ {ok, Key} = public_key:decode_private_key(Der, Pw),
+ Key;
+decode_key(FileOrDer, Pw) ->
+ {ok, [KeyInfo]} = public_key:pem_to_der(FileOrDer),
+ decode_key(KeyInfo, Pw).
+
+encode_key(Key = #'RSAPrivateKey'{}) ->
+ {ok, Der} = 'OTP-PUB-KEY':encode('RSAPrivateKey', Key),
+ {rsa_private_key, list_to_binary(Der), not_encrypted};
+encode_key(Key = #'DSAPrivateKey'{}) ->
+ {ok, Der} = 'OTP-PUB-KEY':encode('DSAPrivateKey', Key),
+ {dsa_private_key, list_to_binary(Der), not_encrypted}.
+
+make_tbs(SubjectKey, Opts) ->
+ Version = list_to_atom("v"++integer_to_list(proplists:get_value(version, Opts, 3))),
+ {Issuer, IssuerKey} = issuer(Opts, SubjectKey),
+
+ {Algo, Parameters} = sign_algorithm(IssuerKey, Opts),
+
+ SignAlgo = #'SignatureAlgorithm'{algorithm = Algo,
+ parameters = Parameters},
+
+ {#'OTPTBSCertificate'{serialNumber = trunc(random:uniform()*100000000)*10000 + 1,
+ signature = SignAlgo,
+ issuer = Issuer,
+ validity = validity(Opts),
+ subject = subject(proplists:get_value(subject, Opts),false),
+ subjectPublicKeyInfo = publickey(SubjectKey),
+ version = Version,
+ extensions = extensions(Opts)
+ }, IssuerKey}.
+
+issuer(Opts, SubjectKey) ->
+ IssuerProp = proplists:get_value(issuer, Opts, true),
+ case IssuerProp of
+ true -> %% Self signed
+ {subject(proplists:get_value(subject, Opts), true), SubjectKey};
+ {Issuer, IssuerKey} when is_binary(Issuer) ->
+ {issuer_der(Issuer), decode_key(IssuerKey)};
+ {File, IssuerKey} when is_list(File) ->
+ {ok, [{cert, Cert, _}|_]} = public_key:pem_to_der(File),
+ {issuer_der(Cert), decode_key(IssuerKey)}
+ end.
+
+issuer_der(Issuer) ->
+ {ok, Decoded} = public_key:pkix_decode_cert(Issuer, otp),
+ #'OTPCertificate'{tbsCertificate=Tbs} = Decoded,
+ #'OTPTBSCertificate'{subject=Subject} = Tbs,
+ Subject.
+
+subject(undefined, IsCA) ->
+ User = if IsCA -> "CA"; true -> os:getenv("USER") end,
+ Opts = [{email, User ++ "@erlang.org"},
+ {name, User},
+ {city, "Stockholm"},
+ {country, "SE"},
+ {org, "erlang"},
+ {org_unit, "testing dep"}],
+ subject(Opts);
+subject(Opts, _) ->
+ subject(Opts).
+
+subject(SubjectOpts) when is_list(SubjectOpts) ->
+ Encode = fun(Opt) ->
+ {Type,Value} = subject_enc(Opt),
+ [#'AttributeTypeAndValue'{type=Type, value=Value}]
+ end,
+ {rdnSequence, [Encode(Opt) || Opt <- SubjectOpts]}.
+
+%% Fill in the blanks
+subject_enc({name, Name}) -> {?'id-at-commonName', {printableString, Name}};
+subject_enc({email, Email}) -> {?'id-emailAddress', Email};
+subject_enc({city, City}) -> {?'id-at-localityName', {printableString, City}};
+subject_enc({state, State}) -> {?'id-at-stateOrProvinceName', {printableString, State}};
+subject_enc({org, Org}) -> {?'id-at-organizationName', {printableString, Org}};
+subject_enc({org_unit, OrgUnit}) -> {?'id-at-organizationalUnitName', {printableString, OrgUnit}};
+subject_enc({country, Country}) -> {?'id-at-countryName', Country};
+subject_enc({serial, Serial}) -> {?'id-at-serialNumber', Serial};
+subject_enc({title, Title}) -> {?'id-at-title', {printableString, Title}};
+subject_enc({dnQualifer, DnQ}) -> {?'id-at-dnQualifier', DnQ};
+subject_enc(Other) -> Other.
+
+
+extensions(Opts) ->
+ case proplists:get_value(extensions, Opts, []) of
+ false ->
+ asn1_NOVALUE;
+ Exts ->
+ lists:flatten([extension(Ext) || Ext <- default_extensions(Exts)])
+ end.
+
+default_extensions(Exts) ->
+ Def = [{key_usage,undefined},
+ {subject_altname, undefined},
+ {issuer_altname, undefined},
+ {basic_constraints, default},
+ {name_constraints, undefined},
+ {policy_constraints, undefined},
+ {ext_key_usage, undefined},
+ {inhibit_any, undefined},
+ {auth_key_id, undefined},
+ {subject_key_id, undefined},
+ {policy_mapping, undefined}],
+ Filter = fun({Key, _}, D) -> lists:keydelete(Key, 1, D) end,
+ Exts ++ lists:foldl(Filter, Def, Exts).
+
+extension({_, undefined}) -> [];
+extension({basic_constraints, Data}) ->
+ case Data of
+ default ->
+ #'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = #'BasicConstraints'{cA=true},
+ critical=true};
+ false ->
+ [];
+ Len when is_integer(Len) ->
+ #'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = #'BasicConstraints'{cA=true, pathLenConstraint=Len},
+ critical=true};
+ _ ->
+ #'Extension'{extnID = ?'id-ce-basicConstraints',
+ extnValue = Data}
+ end;
+extension({Id, Data, Critical}) ->
+ #'Extension'{extnID = Id, extnValue = Data, critical = Critical}.
+
+
+publickey(#'RSAPrivateKey'{modulus=N, publicExponent=E}) ->
+ Public = #'RSAPublicKey'{modulus=N, publicExponent=E},
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?rsaEncryption, parameters='NULL'},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo,
+ subjectPublicKey = Public};
+publickey(#'DSAPrivateKey'{p=P, q=Q, g=G, y=Y}) ->
+ Algo = #'PublicKeyAlgorithm'{algorithm= ?'id-dsa',
+ parameters=#'Dss-Parms'{p=P, q=Q, g=G}},
+ #'OTPSubjectPublicKeyInfo'{algorithm = Algo, subjectPublicKey = Y}.
+
+validity(Opts) ->
+ DefFrom0 = date(),
+ DefTo0 = calendar:gregorian_days_to_date(calendar:date_to_gregorian_days(date())+7),
+ {DefFrom, DefTo} = proplists:get_value(validity, Opts, {DefFrom0, DefTo0}),
+ Format = fun({Y,M,D}) -> lists:flatten(io_lib:format("~w~2..0w~2..0w000000Z",[Y,M,D])) end,
+ #'Validity'{notBefore={generalTime, Format(DefFrom)},
+ notAfter ={generalTime, Format(DefTo)}}.
+
+sign_algorithm(#'RSAPrivateKey'{}, Opts) ->
+ Type = case proplists:get_value(digest, Opts, sha1) of
+ sha1 -> ?'sha1WithRSAEncryption';
+ sha512 -> ?'sha512WithRSAEncryption';
+ sha384 -> ?'sha384WithRSAEncryption';
+ sha256 -> ?'sha256WithRSAEncryption';
+ md5 -> ?'md5WithRSAEncryption';
+ md2 -> ?'md2WithRSAEncryption'
+ end,
+ {Type, 'NULL'};
+sign_algorithm(#'DSAPrivateKey'{p=P, q=Q, g=G}, _Opts) ->
+ {?'id-dsa-with-sha1', #'Dss-Parms'{p=P, q=Q, g=G}}.
+
+make_key(rsa, _Opts) ->
+ %% (OBS: for testing only)
+ gen_rsa2(64);
+make_key(dsa, _Opts) ->
+ gen_dsa2(128, 20). %% Bytes i.e. {1024, 160}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% RSA key generation (OBS: for testing only)
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+-define(SMALL_PRIMES, [65537,97,89,83,79,73,71,67,61,59,53,
+ 47,43,41,37,31,29,23,19,17,13,11,7,5,3]).
+
+gen_rsa2(Size) ->
+ P = prime(Size),
+ Q = prime(Size),
+ N = P*Q,
+ Tot = (P - 1) * (Q - 1),
+ [E|_] = lists:dropwhile(fun(Candidate) -> (Tot rem Candidate) == 0 end, ?SMALL_PRIMES),
+ {D1,D2} = extended_gcd(E, Tot),
+ D = erlang:max(D1,D2),
+ case D < E of
+ true ->
+ gen_rsa2(Size);
+ false ->
+ {Co1,Co2} = extended_gcd(Q, P),
+ Co = erlang:max(Co1,Co2),
+ #'RSAPrivateKey'{version = 'two-prime',
+ modulus = N,
+ publicExponent = E,
+ privateExponent = D,
+ prime1 = P,
+ prime2 = Q,
+ exponent1 = D rem (P-1),
+ exponent2 = D rem (Q-1),
+ coefficient = Co
+ }
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% DSA key generation (OBS: for testing only)
+%% See http://en.wikipedia.org/wiki/Digital_Signature_Algorithm
+%% and the fips_186-3.pdf
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+gen_dsa2(LSize, NSize) ->
+ Q = prime(NSize), %% Choose N-bit prime Q
+ X0 = prime(LSize),
+ P0 = prime((LSize div 2) +1),
+
+ %% Choose L-bit prime modulus P such that p–1 is a multiple of q.
+ case dsa_search(X0 div (2*Q*P0), P0, Q, 1000) of
+ error ->
+ gen_dsa2(LSize, NSize);
+ P ->
+ G = crypto:mod_exp(2, (P-1) div Q, P), % Choose G a number whose multiplicative order modulo p is q.
+ %% such that This may be done by setting g = h^(p–1)/q mod p, commonly h=2 is used.
+
+ X = prime(20), %% Choose x by some random method, where 0 < x < q.
+ Y = crypto:mod_exp(G, X, P), %% Calculate y = g^x mod p.
+
+ #'DSAPrivateKey'{version=0, p=P, q=Q, g=G, y=Y, x=X}
+ end.
+
+%% See fips_186-3.pdf
+dsa_search(T, P0, Q, Iter) when Iter > 0 ->
+ P = 2*T*Q*P0 + 1,
+ case is_prime(crypto:mpint(P), 50) of
+ true -> P;
+ false -> dsa_search(T+1, P0, Q, Iter-1)
+ end;
+dsa_search(_,_,_,_) ->
+ error.
+
+
+%%%%%%% Crypto Math %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+prime(ByteSize) ->
+ Rand = odd_rand(ByteSize),
+ crypto:erlint(prime_odd(Rand, 0)).
+
+prime_odd(Rand, N) ->
+ case is_prime(Rand, 50) of
+ true ->
+ Rand;
+ false ->
+ NotPrime = crypto:erlint(Rand),
+ prime_odd(crypto:mpint(NotPrime+2), N+1)
+ end.
+
+%% see http://en.wikipedia.org/wiki/Fermat_primality_test
+is_prime(_, 0) -> true;
+is_prime(Candidate, Test) ->
+ CoPrime = odd_rand(<<0,0,0,4, 10000:32>>, Candidate),
+ case crypto:mod_exp(CoPrime, Candidate, Candidate) of
+ CoPrime -> is_prime(Candidate, Test-1);
+ _ -> false
+ end.
+
+odd_rand(Size) ->
+ Min = 1 bsl (Size*8-1),
+ Max = (1 bsl (Size*8))-1,
+ odd_rand(crypto:mpint(Min), crypto:mpint(Max)).
+
+odd_rand(Min,Max) ->
+ Rand = <<Sz:32, _/binary>> = crypto:rand_uniform(Min,Max),
+ BitSkip = (Sz+4)*8-1,
+ case Rand of
+ Odd = <<_:BitSkip, 1:1>> -> Odd;
+ Even = <<_:BitSkip, 0:1>> ->
+ crypto:mpint(crypto:erlint(Even)+1)
+ end.
+
+extended_gcd(A, B) ->
+ case A rem B of
+ 0 ->
+ {0, 1};
+ N ->
+ {X, Y} = extended_gcd(B, N),
+ {Y, X-Y*(A div B)}
+ end.
diff --git a/lib/public_key/test/public_key.cover b/lib/public_key/test/public_key.cover
new file mode 100644
index 0000000000..8477c76ef6
--- /dev/null
+++ b/lib/public_key/test/public_key.cover
@@ -0,0 +1,2 @@
+
+{exclude, ['OTP-PUB-KEY']}. \ No newline at end of file
diff --git a/lib/public_key/test/public_key_SUITE.erl b/lib/public_key/test/public_key_SUITE.erl
index 8cc36e490d..6a3d6bfcf5 100644
--- a/lib/public_key/test/public_key_SUITE.erl
+++ b/lib/public_key/test/public_key_SUITE.erl
@@ -101,14 +101,13 @@ all(doc) ->
all(suite) ->
[app,
+ dh,
pem_to_der,
- decode_private_key
-%% encrypt_decrypt,
-%% rsa_verify
-%% dsa_verify_sign,
-%% pkix_encode_decode,
-%% pkix_verify_sign,
-%% pkix_path_validation
+ decode_private_key,
+ encrypt_decrypt,
+ sign_verify,
+ pkix,
+ pkix_path_validation
].
%% Test cases starts here.
@@ -118,20 +117,35 @@ app(doc) ->
"Test that the public_key app file is ok";
app(suite) ->
[];
-app(Config) when list(Config) ->
+app(Config) when is_list(Config) ->
ok = test_server:app_test(public_key).
+dh(doc) ->
+ "Test diffie-hellman functions file is ok";
+dh(suite) ->
+ [];
+dh(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+ {ok,[DerDHparams = {dh_params, _, _}]} =
+ public_key:pem_to_der(filename:join(Datadir, "dh.pem")),
+ {ok, DHps = #'DHParameter'{prime=P,base=G}} = public_key:decode_dhparams(DerDHparams),
+ DHKeys = {Private,_Public} = public_key:gen_key(DHps),
+ test_server:format("DHparams = ~p~nDH Keys~p~n", [DHps, DHKeys]),
+ {_Private,_Public2} = pubkey_crypto:gen_key(diffie_hellman, [crypto:erlint(Private), P, G]),
+ ok.
+
+
pem_to_der(doc) ->
["Check that supported PEM files are decoded into the expected entry type"];
pem_to_der(suite) ->
[];
pem_to_der(Config) when is_list(Config) ->
Datadir = ?config(data_dir, Config),
- {ok,[{dsa_private_key, _, not_encrypted}]} =
+ {ok,DSAKey =[{dsa_private_key, _, not_encrypted}]} =
public_key:pem_to_der(filename:join(Datadir, "dsa.pem")),
{ok,[{rsa_private_key, _, _}]} =
public_key:pem_to_der(filename:join(Datadir, "client_key.pem")),
- {ok,[{rsa_private_key, _, _}]} =
+ {ok, [{rsa_private_key, _, _}]} =
public_key:pem_to_der(filename:join(Datadir, "rsa.pem")),
{ok,[{rsa_private_key, _, _}]} =
public_key:pem_to_der(filename:join(Datadir, "rsa.pem"), "abcd1234"),
@@ -144,12 +158,18 @@ pem_to_der(Config) when is_list(Config) ->
public_key:pem_to_der(filename:join(Datadir, "client_cert.pem")),
{ok,[{cert_req, _, _}]} =
public_key:pem_to_der(filename:join(Datadir, "req.pem")),
- {ok,[{cert, _, _}, {cert, _, _}]} =
+ {ok, Certs = [{cert, _, _}, {cert, _, _}]} =
public_key:pem_to_der(filename:join(Datadir, "cacerts.pem")),
- {ok, Bin1} = file:read_file(filename:join(Datadir, "cacerts.pem")),
+ {ok, Bin1} = file:read_file(filename:join(Datadir, "cacerts.pem")),
{ok, [{cert, _, _}, {cert, _, _}]} = public_key:pem_to_der(Bin1),
+
+ ok = public_key:der_to_pem(filename:join(Datadir, "wcacerts.pem"), Certs),
+ ok = public_key:der_to_pem(filename:join(Datadir, "wdsa.pem"), DSAKey),
+ {ok, Certs} = public_key:pem_to_der(filename:join(Datadir, "wcacerts.pem")),
+ {ok, DSAKey} = public_key:pem_to_der(filename:join(Datadir, "wdsa.pem")),
+
ok.
%%--------------------------------------------------------------------
decode_private_key(doc) ->
@@ -178,84 +198,148 @@ encrypt_decrypt(doc) ->
encrypt_decrypt(suite) ->
[];
encrypt_decrypt(Config) when is_list(Config) ->
- RSAPrivateKey = #'RSAPrivateKey'{publicExponent = 17,
- modulus = 3233,
- privateExponent = 2753,
- prime1 = 61,
- prime2 = 53,
- version = 'two-prime'},
- Msg = <<0,123>>,
- {ok, Encrypted} = public_key:encrypt(Msg, RSAPrivateKey, [{block_type, 2}]),
- test_server:format("Expected 855, Encrypted ~p ~n", [Encrypted]),
+ {PrivateKey, _DerKey} = pkey_test:gen_rsa(64),
+ #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp} = PrivateKey,
+ PublicKey = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp},
+ Msg = list_to_binary(lists:duplicate(5, "Foo bar 100")),
+ RsaEncrypted = public_key:encrypt_private(Msg, PrivateKey),
+ Msg = public_key:decrypt_public(RsaEncrypted, PublicKey),
+ Msg = public_key:decrypt_public(RsaEncrypted, PrivateKey),
+ RsaEncrypted2 = public_key:encrypt_public(Msg, PublicKey),
+ RsaEncrypted3 = public_key:encrypt_public(Msg, PrivateKey),
+ Msg = public_key:decrypt_private(RsaEncrypted2, PrivateKey),
+ Msg = public_key:decrypt_private(RsaEncrypted3, PrivateKey),
+
ok.
+
+%%--------------------------------------------------------------------
+sign_verify(doc) ->
+ ["Checks that we can sign and verify signatures."];
+sign_verify(suite) ->
+ [];
+sign_verify(Config) when is_list(Config) ->
+ %% Make cert signs and validates the signature using RSA and DSA
+ Ca = {_, CaKey} = pkey_test:make_cert([]),
+ {ok, PrivateRSA = #'RSAPrivateKey'{modulus=Mod, publicExponent=Exp}} =
+ public_key:decode_private_key(CaKey),
+
+ CertInfo = {Cert1,CertKey1} = pkey_test:make_cert([{key, dsa}, {issuer, Ca}]),
+
+ PublicRSA = #'RSAPublicKey'{modulus=Mod, publicExponent=Exp},
+ true = public_key:verify_signature(Cert1, PublicRSA, undefined),
+
+ {Cert2,_CertKey} = pkey_test:make_cert([{issuer, CertInfo}]),
+
+ {ok, #'DSAPrivateKey'{p=P, q=Q, g=G, y=Y, x=_X}} =
+ public_key:decode_private_key(CertKey1),
+ true = public_key:verify_signature(Cert2, Y, #'Dss-Parms'{p=P, q=Q, g=G}),
+ %% RSA sign
+ Msg0 = lists:duplicate(5, "Foo bar 100"),
+ Msg = list_to_binary(Msg0),
+ RSASign = public_key:sign(sha, Msg0, PrivateRSA),
+ RSASign = public_key:sign(Msg, PrivateRSA),
+ true = public_key:verify_signature(Msg, sha, RSASign, PublicRSA),
+ false = public_key:verify_signature(<<1:8, Msg/binary>>, sha, RSASign, PublicRSA),
+ false = public_key:verify_signature(Msg, sha, <<1:8, RSASign/binary>>, PublicRSA),
+ RSASign = public_key:sign(sha, Msg, PrivateRSA),
+ RSASign1 = public_key:sign(md5, Msg, PrivateRSA),
+ true = public_key:verify_signature(Msg, md5, RSASign1, PublicRSA),
+
+ %% DSA sign
+ Datadir = ?config(data_dir, Config),
+ {ok,[DsaKey = {dsa_private_key, _, _}]} =
+ public_key:pem_to_der(filename:join(Datadir, "dsa.pem")),
+ {ok, DSAPrivateKey} = public_key:decode_private_key(DsaKey),
+ #'DSAPrivateKey'{p=P1, q=Q1, g=G1, y=Y1, x=_X1} = DSAPrivateKey,
+ DSASign = public_key:sign(Msg, DSAPrivateKey),
+ DSAPublicKey = Y1,
+ DSAParams = #'Dss-Parms'{p=P1, q=Q1, g=G1},
+ true = public_key:verify_signature(Msg, sha, DSASign, DSAPublicKey, DSAParams),
+ false = public_key:verify_signature(<<1:8, Msg/binary>>, sha, DSASign, DSAPublicKey, DSAParams),
+ false = public_key:verify_signature(Msg, sha, <<1:8, DSASign/binary>>, DSAPublicKey, DSAParams),
+
+ ok.
+pkix(doc) ->
+ "Misc pkix tests not covered elsewhere";
+pkix(suite) ->
+ [];
+pkix(Config) when is_list(Config) ->
+ Datadir = ?config(data_dir, Config),
+ {ok,Certs0} = public_key:pem_to_der(filename:join(Datadir, "cacerts.pem")),
+ {ok,Certs1} = public_key:pem_to_der(filename:join(Datadir, "client_cert.pem")),
+ TestTransform = fun({cert, CertDer, not_encrypted}) ->
+ {ok, PlainCert} = public_key:pkix_decode_cert(CertDer, plain),
+ {ok, OtpCert} = public_key:pkix_decode_cert(CertDer, otp),
+ CertDer = public_key:pkix_encode_cert(OtpCert),
+ CertDer = public_key:pkix_encode_cert(PlainCert),
+ OTPSubj = (OtpCert#'OTPCertificate'.tbsCertificate)#'OTPTBSCertificate'.subject,
+ Subj = public_key:pkix_transform(OTPSubj, encode),
+ {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj),
+ Subj2 = (PlainCert#'Certificate'.tbsCertificate)#'TBSCertificate'.subject,
+ {ok, DNEncoded} = 'OTP-PUB-KEY':encode('Name', Subj2),
+ OTPSubj = public_key:pkix_transform(Subj2, decode),
+ false = public_key:pkix_is_fixed_dh_cert(CertDer)
+ end,
+ [TestTransform(Cert) || Cert <- Certs0 ++ Certs1],
+ true = public_key:pkix_is_self_signed(element(2,hd(Certs0))),
+ false = public_key:pkix_is_self_signed(element(2,hd(Certs1))),
+ CaIds = [element(2, public_key:pkix_issuer_id(Cert, self)) || {cert, Cert, _} <- Certs0],
+ {ok, IssuerId = {_, IssuerName}} = public_key:pkix_issuer_id(element(2,hd(Certs1)), other),
+ true = lists:member(IssuerId, CaIds),
+ %% Should be normalized allready
+ TestStr = {rdnSequence, [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"ERLANGCA"}}],
+ [{'AttributeTypeAndValue', {2,5,4,3},{printableString," erlang ca "}}]]},
+ VerifyStr = {rdnSequence, [[{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlang ca"}}],
+ [{'AttributeTypeAndValue', {2,5,4,3},{printableString,"erlangca"}}]]},
+ VerifyStr = public_key:pkix_normalize_general_name(TestStr),
-%% Datadir = ?config(data_dir, Config),
-%% {ok,[{rsa_private_key, EncKey}]} =
-%% public_key:pem_to_der(filename:join(Datadir, "server_key.pem")),
-%% {ok, Key} = public_key:decode_private_key(EncKey, rsa),
-%% RSAPublicKey = #'RSAPublicKey'{publicExponent =
-%% Key#'RSAPrivateKey'.publicExponent,
-%% modulus = Key#'RSAPrivateKey'.modulus},
-%% {ok, Msg} = file:read_file(filename:join(Datadir, "msg.txt")),
-%% Hash = crypto:sha(Msg),
-%% {ok, Encrypted} = public_key:encrypt(Hash, Key, [{block_type, 2}]),
-%% test_server:format("Encrypted ~p", [Encrypted]),
-%% {ok, Decrypted} = public_key:decrypt(Encrypted,
-%% RSAPublicKey, [{block_type, 1}]),
-%% test_server:format("Encrypted ~p", [Decrypted]),
-%% true = Encrypted == Decrypted.
-
-%%--------------------------------------------------------------------
-rsa_verify(doc) ->
- ["Cheks that we can verify an rsa signature."];
-rsa_verify(suite) ->
+ ok.
+
+pkix_path_validation(doc) ->
+ "Misc pkix tests not covered elsewhere";
+pkix_path_validation(suite) ->
[];
-rsa_verify(Config) when is_list(Config) ->
- Datadir = ?config(data_dir, Config),
-
- {ok,[{cert, DerCert}]} =
- public_key:pem_to_der(filename:join(Datadir, "server_cert.pem")),
+pkix_path_validation(Config) when is_list(Config) ->
+ CaK = {Trusted,_} =
+ pkey_test:make_cert([{key, dsa},
+ {subject, [
+ {name, "Public Key"},
+ {?'id-at-name', {printableString, "public_key"}},
+ {?'id-at-pseudonym', {printableString, "pubkey"}},
+ {city, "Stockholm"},
+ {country, "SE"},
+ {org, "erlang"},
+ {org_unit, "testing dep"}
+ ]}
+ ]),
+ ok = pkey_test:write_pem("/tmp", "cacert", CaK),
+
+ CertK1 = {Cert1, _} = pkey_test:make_cert([{issuer, CaK}]),
+ CertK2 = {Cert2,_} = pkey_test:make_cert([{issuer, CertK1}, {digest, md5}, {extensions, false}]),
+ ok = pkey_test:write_pem("/tmp", "cert", CertK2),
+
+ {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1], []),
- {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp),
+ {error, {bad_cert,invalid_issuer}} = public_key:pkix_path_validation(Trusted, [Cert2], []),
+ %%{error, {bad_cert,invalid_issuer}} = public_key:pkix_path_validation(Trusted, [Cert2], [{verify,false}]),
- {0, Signature} = OTPCert#'Certificate'.signature,
- TBSCert = OTPCert#'Certificate'.tbsCertificate,
+ {ok, _} = public_key:pkix_path_validation(Trusted, [Cert1, Cert2], []),
+ {error, issuer_not_found} = public_key:pkix_issuer_id(Cert2, other),
- #'TBSCertificate'{subjectPublicKeyInfo = Info} = TBSCert,
+ CertK3 = {Cert3,_} = pkey_test:make_cert([{issuer, CertK1}, {extensions, [{basic_constraints, false}]}]),
+ {Cert4,_} = pkey_test:make_cert([{issuer, CertK3}]),
+ {error, E={bad_cert,missing_basic_constraint}} =
+ public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], []),
- #'SubjectPublicKeyInfo'{subjectPublicKey = RSAPublicKey} = Info,
-
- EncTBSCert = encoded_tbs_cert(DerCert),
- Digest = crypto:sha(EncTBSCert),
-
- public_key:verify_signature(Digest, Signature, RSAPublicKey).
-
-
-%% Signature is generated in the following way (in datadir):
-%% openssl dgst -sha1 -binary -out rsa_signature -sign server_key.pem msg.txt
-%%{ok, Signature} = file:read_file(filename:join(Datadir, "rsa_signature")),
-%%{ok, Signature} = file:read_file(filename:join(Datadir, "rsa_signature")),
-%% {ok, Msg} = file:read_file(filename:join(Datadir, "msg.txt")),
-%% Digest = crypto:sha(Msg),
-%% {ok,[{rsa_private_key, EncKey}]} =
-%% public_key:pem_to_der(filename:join(Datadir, "server_key.pem")),
-%% {ok, Key} = public_key:decode_private_key(EncKey, rsa),
-%% RSAPublicKey = #'RSAPublicKey'{publicExponent =
-%% Key#'RSAPrivateKey'.publicExponent,
-%% modulus = Key#'RSAPrivateKey'.modulus},
-
-encoded_tbs_cert(Cert) ->
- {ok, PKIXCert} =
- 'OTP-PUB-KEY':decode_TBSCert_exclusive(Cert),
- {'Certificate',
- {'Certificate_tbsCertificate', EncodedTBSCert}, _, _} = PKIXCert,
- EncodedTBSCert.
+ {ok, {_,_,[E]}} = public_key:pkix_path_validation(Trusted, [Cert1, Cert3,Cert4], [{verify,false}]),
+ % test_server:format("PV ~p ~n", [Result]),
+ ok.
diff --git a/lib/public_key/vsn.mk b/lib/public_key/vsn.mk
index da1465d538..8c4e4127b2 100644
--- a/lib/public_key/vsn.mk
+++ b/lib/public_key/vsn.mk
@@ -1,7 +1,10 @@
-PUBLIC_KEY_VSN = 0.6
-TICKETS = OTP-7046 \
- OTP-8553
-#TICKETS_o.5 = OTP-8372
+PUBLIC_KEY_VSN = 0.7
+
+TICKETS = OTP-8626
+
+#TICKETS_0.6 = OTP-7046 \
+# OTP-8553
+#TICKETS_0.5 = OTP-8372
#TICKETS_0.4 = OTP-8250
#TICKETS_0.3 = OTP-8100 OTP-8142
#TICKETS_0.2 = OTP-7860
diff --git a/lib/snmp/doc/src/notes.xml b/lib/snmp/doc/src/notes.xml
index eb7c9db6ba..3f4954cfbd 100644
--- a/lib/snmp/doc/src/notes.xml
+++ b/lib/snmp/doc/src/notes.xml
@@ -33,6 +33,61 @@
</header>
<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>
@@ -60,6 +115,12 @@
<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>
@@ -83,6 +144,15 @@
<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>
diff --git a/lib/snmp/doc/src/snmp_app.xml b/lib/snmp/doc/src/snmp_app.xml
index 57eb87a759..694e619da1 100644
--- a/lib/snmp/doc/src/snmp_app.xml
+++ b/lib/snmp/doc/src/snmp_app.xml
@@ -346,7 +346,7 @@
<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>
<tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
diff --git a/lib/snmp/doc/src/snmp_config.xml b/lib/snmp/doc/src/snmp_config.xml
index 5bd36305fc..769b908adc 100644
--- a/lib/snmp/doc/src/snmp_config.xml
+++ b/lib/snmp/doc/src/snmp_config.xml
@@ -343,7 +343,7 @@
<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>
<tag><c><![CDATA[mibs_cache_age() = integer() > 0 <optional>]]></c></tag>
diff --git a/lib/snmp/doc/src/snmpa.xml b/lib/snmp/doc/src/snmpa.xml
index b3661ae9b0..1be6abe6dd 100644
--- a/lib/snmp/doc/src/snmpa.xml
+++ b/lib/snmp/doc/src/snmpa.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>snmpa</title>
@@ -648,6 +648,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 +881,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 +903,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 +1043,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 +1051,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 +1143,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_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/src/agent/snmpa.erl b/lib/snmp/src/agent/snmpa.erl
index a113bba3a7..87b191caed 100644
--- a/lib/snmp/src/agent/snmpa.erl
+++ b/lib/snmp/src/agent/snmpa.erl
@@ -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,
@@ -302,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).
@@ -415,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, "", []).
diff --git a/lib/snmp/src/agent/snmpa_agent.erl b/lib/snmp/src/agent/snmpa_agent.erl
index fb04fca632..f70885b2ec 100644
--- a/lib/snmp/src/agent/snmpa_agent.erl
+++ b/lib/snmp/src/agent/snmpa_agent.erl
@@ -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,
@@ -64,7 +65,7 @@
%% 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/7, worker/2, worker_loop/1, do_send_trap/7]).
-ifndef(default_verbosity).
-define(default_verbosity,silence).
@@ -245,6 +246,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}).
@@ -524,14 +529,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 ->
@@ -540,6 +546,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 --
@@ -626,6 +653,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}.
@@ -719,14 +747,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} ->
@@ -736,17 +765,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} ->
@@ -856,17 +907,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} ->
@@ -876,8 +962,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:"
@@ -1219,6 +1307,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 ->
@@ -1432,17 +1522,20 @@ spawn_thread(Vsn, Pdu, PduMS, ACMData, Address, Extra) ->
Args = [Vsn, Pdu, PduMS, ACMData, Address, 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))),
?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),
@@ -1457,17 +1550,22 @@ worker_loop(Master) ->
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),
+ %% 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;
- {TrapRec, NotifyName, ContextName, Recv, V} -> % We don't trap exits!
+ %% 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, V, get(net_if)),
+ ContextName, Recv, Vbs, LocalEngineID,
+ get(net_if)),
Master ! worker_available;
{verbosity, Verbosity} ->
@@ -1616,13 +1714,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: "
@@ -1639,7 +1739,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
@@ -1676,7 +1777,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
@@ -1693,39 +1795,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 ! {send_trap,
+ TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID},
{ok, S#state{worker_state = busy}}
end.
diff --git a/lib/snmp/src/agent/snmpa_internal.hrl b/lib/snmp/src/agent/snmpa_internal.hrl
index a33a6809dc..9fa874f119 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-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, 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,8 @@
-include_lib("snmp/src/app/snmp_internal.hrl").
+-define(DEFAULT_LOCAL_ENGINE_ID, snmp_framework_mib:get_engine_id()).
+
-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_mib.erl b/lib/snmp/src/agent/snmpa_mib.erl
index 370989d0be..ce90db18b3 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-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT 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).
diff --git a/lib/snmp/src/agent/snmpa_mpd.erl b/lib/snmp/src/agent/snmpa_mpd.erl
index 2e09286b87..fd75b98f84 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-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT 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) ->
@@ -444,17 +464,18 @@ 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 =
+ {#varbind{oid = ?snmpUnknownPDUHandlers,
+ variabletype = 'Counter32',
+ value = Val},
+ SecName,
+ [{securityLevel, SecLevel},
+ {contextEngineID, ContextEngineID},
+ {contextName, 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 +494,7 @@ v3_proc(NoteStore, Packet, V3Hdr, Data, Log) ->
ContextName,
SecData,
PDU,
+ LocalEngineID,
Log);
_ ->
@@ -501,7 +523,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 +538,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 +567,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 +584,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 +595,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 +614,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 +627,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 +642,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 +700,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 +723,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 +731,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 +754,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 +770,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 +782,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 +795,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 +855,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 +868,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 +881,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 +894,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 +1138,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 +1161,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 +1198,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 +1227,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 +1238,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 +1255,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 +1278,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 +1290,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 +1314,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_trap.erl b/lib/snmp/src/agent/snmpa_trap.erl
index b1096b1135..450cb2e9f4 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,20 @@ 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).
+
+send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs, LocalEngineID, NetIf) ->
+ (catch do_send_trap(TrapRec, NotifyName, ContextName, Recv, Vbs,
+ LocalEngineID, NetIf)).
-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 +630,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 +647,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 +657,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 +679,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 +694,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 +715,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 +726,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 +781,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 +868,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 +897,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 +911,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 b94294844b..ae584bb3c1 100644
--- a/lib/snmp/src/agent/snmpa_usm.erl
+++ b/lib/snmp/src/agent/snmpa_usm.erl
@@ -19,8 +19,8 @@
-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",[]),
@@ -418,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
@@ -439,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);
_ ->
@@ -460,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
@@ -474,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]",[]),
@@ -681,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/app/snmp.appup.src b/lib/snmp/src/app/snmp.appup.src
index aa3410fea3..9ad16ffad2 100644
--- a/lib/snmp/src/app/snmp.appup.src
+++ b/lib/snmp/src/app/snmp.appup.src
@@ -22,53 +22,91 @@
%% ----- U p g r a d e -------------------------------------------------------
[
+ {"4.16.2",
+ [
+ {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_agent, soft, soft_purge, soft_purge, []},
+
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []}
+ ]
+ },
{"4.16.1",
[
- {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {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, snmp_pdus, 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_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
]
},
{"4.16",
[
- {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
- {load_module, snmp_usm, 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, []},
- {update, snmpm_net_if, soft, 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_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+
+ {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, []}
]
},
{"4.15",
[
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmpa, soft_purge, soft_purge, [snmp_log]},
{load_module, snmp_config, 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, [snmp_log, snmpa_agent]},
{load_module, snmpa_general_db, soft_purge, soft_purge, []},
- {update, snmpm_net_if, {advanced, upgrade_from_pre_4_16},
- soft_purge, soft_purge, [snmpm_config, snmp_log]},
- {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16},
- soft_purge, soft_purge, [snmpa_agent, snmp_log]},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
{load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
- {load_module, snmp_usm, soft_purge, soft_purge, []},
+ {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16},
+ soft_purge, soft_purge, [snmpa_agent, snmp_log]},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
- {update, snmpm_config, soft, soft_purge, soft_purge, []}
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_net_if, {advanced, upgrade_from_pre_4_16},
+ soft_purge, soft_purge, [snmpm_config, snmp_log]},
+ {update, snmpm_config, soft, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
]
},
{"4.14",
[
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmpa, soft_purge, soft_purge, [snmp_log]},
{load_module, snmp_config, 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, [snmp_log, snmpa_agent]},
{load_module, snmpa_general_db, soft_purge, soft_purge, []},
- {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16},
- soft_purge, soft_purge, [snmpa_agent, snmp_log]},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
{load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
- {load_module, snmp_usm, soft_purge, soft_purge, []},
+ {update, snmpa_net_if, {advanced, upgrade_from_pre_4_16},
+ soft_purge, soft_purge, [snmp_log, snmpa_agent]},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
{load_module, snmpm_user, soft_purge, soft_purge, []},
{load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
{update, snmpm_net_if, {advanced, upgrade_from_pre_4_16},
@@ -80,18 +118,22 @@
},
{"4.13.5",
[
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmpa_mib_data, soft_purge, soft_purge, []},
- {load_module, snmpa, soft_purge, soft_purge, [snmp_log]},
{load_module, snmp_config, 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, [snmp_log, snmpa_agent]},
{load_module, snmpa_general_db, soft_purge, soft_purge, []},
+ {load_module, snmpa_mib_data, 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_net_if, {advanced, upgrade_from_pre_4_16},
soft_purge, soft_purge, [snmpa_agent, snmp_log]},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
- {load_module, snmp_usm, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, [snmpa_mib_data]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
{load_module, snmpm_user, soft_purge, soft_purge, []},
{load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
{update, snmpm_net_if, {advanced, upgrade_from_pre_4_14},
@@ -107,54 +149,92 @@
%% ------D o w n g r a d e ---------------------------------------------------
[
+ {"4.16.2",
+ [
+ {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_agent, soft, soft_purge, soft_purge, []},
+
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []}
+ ]
+ },
{"4.16.1",
[
- {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {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, snmp_pdus, 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_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
]
},
{"4.16",
[
- {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
- {load_module, snmp_usm, 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, []},
- {update, snmpm_net_if, soft, 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_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+
+ {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, []}
]
},
{"4.15",
[
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmpa, soft_purge, soft_purge, [snmp_log]},
{load_module, snmp_config, soft_purge, soft_purge, []},
{load_module, snmp_log, soft_purge, soft_purge, []},
- {load_module, snmpa_general_db, soft_purge, soft_purge, []},
- {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16},
- soft_purge, soft_purge, [snmpa_agent, snmp_log]},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {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, snmp_log]},
{load_module, snmpa_general_db, soft_purge, soft_purge, []},
- {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
+ {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
+ {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16},
+ soft_purge, soft_purge, [snmpa_agent, snmp_log]},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
+ {update, snmpm_net_if, {advanced, downgrade_to_pre_4_16},
soft_purge, soft_purge, [snmpm_config, snmp_log]},
- {update, snmpm_config, soft, soft_purge, soft_purge, []}
+ {update, snmpm_config, soft, soft_purge, soft_purge, []},
+ {update, snmpm_server, soft, soft_purge, soft_purge, []}
]
},
{"4.14",
[
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmpa, soft_purge, soft_purge, [snmp_log]},
{load_module, snmp_config, 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, snmp_log]},
{load_module, snmpa_general_db, soft_purge, soft_purge, []},
- {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16},
- soft_purge, soft_purge, [snmpa_agent, snmp_log]},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
+ {load_module, snmpa_mpd, soft_purge, soft_purge, [snmpa_usm]},
{load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
- {load_module, snmp_usm, soft_purge, soft_purge, []},
+ {update, snmpa_net_if, {advanced, downgrade_to_pre_4_16},
+ soft_purge, soft_purge, [snmpa_agent, snmp_log]},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, []},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
{load_module, snmpm_user, soft_purge, soft_purge, []},
{load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
{update, snmpm_net_if, {advanced, downgrade_to_pre_4_16},
@@ -166,18 +246,22 @@
},
{"4.13.5",
[
- {load_module, snmp_pdus, soft_purge, soft_purge, []},
- {load_module, snmpa_mib_data, soft_purge, soft_purge, []},
{load_module, snmp_config, soft_purge, soft_purge, []},
- {load_module, snmpa, soft_purge, soft_purge, [snmp_log]},
{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, [snmp_log, snmpa_agent]},
{load_module, snmpa_general_db, soft_purge, soft_purge, []},
+ {load_module, snmpa_mib_data, 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_net_if, {advanced, downgrade_to_pre_4_16},
soft_purge, soft_purge, [snmpa_agent, snmp_log]},
- {update, snmpa_agent, soft, soft_purge, soft_purge, []},
- {load_module, snmpa_usm, soft_purge, soft_purge, [snmp_usm]},
- {load_module, snmp_usm, soft_purge, soft_purge, []},
+ {update, snmpa_mib, soft, soft_purge, soft_purge, [snmpa_mib_data]},
+ {update, snmpa_agent, soft, soft_purge, soft_purge, [snmpa_mib]},
+ {load_module, snmpm_mpd, soft_purge, soft_purge, []},
{load_module, snmpm_user, soft_purge, soft_purge, []},
{load_module, snmpm_user_default, soft_purge, soft_purge, [snmpm_user]},
{update, snmpm_net_if, {advanced, downgrade_to_pre_4_14},
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_server.erl b/lib/snmp/src/manager/snmpm_server.erl
index 30aacc0ec3..d64b5b1d53 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-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -2804,16 +2804,16 @@ 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 +2829,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 +2848,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/test/snmp_agent_test.erl b/lib/snmp/test/snmp_agent_test.erl
index af0581150a..2534147769 100644
--- a/lib/snmp/test/snmp_agent_test.erl
+++ b/lib/snmp/test/snmp_agent_test.erl
@@ -1046,7 +1046,7 @@ v1_cases() ->
sparse_table,
cnt_64,
opaque,
-
+
change_target_addr_config
].
@@ -1977,7 +1977,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>
@@ -3446,7 +3447,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
@@ -3457,10 +3458,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"}]).
@@ -3509,7 +3510,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"}]),
@@ -3517,7 +3519,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 => "
@@ -6219,12 +6221,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..9e89aa889c 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-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -421,7 +421,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),
diff --git a/lib/snmp/vsn.mk b/lib/snmp/vsn.mk
index 7a588da9cc..4ca1fb7901 100644
--- a/lib/snmp/vsn.mk
+++ b/lib/snmp/vsn.mk
@@ -17,162 +17,41 @@
#
# %CopyrightEnd%
-SNMP_VSN = 4.16.2
-PRE_VSN =-OTP8604
+SNMP_VSN = 4.17
+PRE_VSN =
APP_VSN = "snmp-$(SNMP_VSN)$(PRE_VSN)"
-TICKETS = OTP-8563 OTP-8574 OTP-8594 OTP-8595
+TICKETS = OTP-8478
-TICKETS_4_16_1 = OTP-8480 OTP-8481
+TICKETS_4_16_2 = \
+ OTP-8563 \
+ OTP-8574 \
+ OTP-8594 \
+ OTP-8595 \
+ OTP-8646 \
+ OTP-8648
+
+TICKETS_4_16_1 = \
+ OTP-8480 \
+ OTP-8481
TICKETS_4_16 = \
OTP-8395 \
OTP-8433 \
OTP-8442
-TICKETS_4_15 = OTP-8229 OTP-8249
-
-TICKETS_4_14 = OTP-8223 OTP-8228 OTP-8237
-
-TICKETS_4_13_5 = OTP-8116 OTP-8120 OTP-8181 OTP-8182
-
-TICKETS_4_13_4 = OTP-8044 OTP-8062 OTP-8098
-
-TICKETS_4_13_3 = OTP-8015 OTP-8020
-
-TICKETS_4_13_2 = OTP-7961 OTP-7977 OTP-7983 OTP-7989
-
-TICKETS_4_13_1 = OTP-7902
-
-TICKETS_4_13 = OTP-7571 OTP-7735 OTP-7836 OTP-7851
-
-TICKETS_4_12_2 = OTP-7868
-
-TICKETS_4_12_1 = OTP-7695 OTP-7698
-
-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_15 = \
+ OTP-8229 \
+ OTP-8249
-TICKETS_4_3 = \
- OTP-5636 \
- OTP-5637 \
- OTP-5490
+TICKETS_4_14 = \
+ OTP-8223 \
+ OTP-8228 \
+ OTP-8237
-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/notes.xml b/lib/ssh/doc/src/notes.xml
index 67a226f726..7c8735cf56 100644
--- a/lib/ssh/doc/src/notes.xml
+++ b/lib/ssh/doc/src/notes.xml
@@ -37,6 +37,18 @@
<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>
diff --git a/lib/ssh/src/ssh_acceptor.erl b/lib/ssh/src/ssh_acceptor.erl
index 57229daa27..9060626ab3 100644
--- a/lib/ssh/src/ssh_acceptor.erl
+++ b/lib/ssh/src/ssh_acceptor.erl
@@ -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_cli.erl b/lib/ssh/src/ssh_cli.erl
index 2764ea2e43..e3b6ffa125 100644
--- a/lib/ssh/src/ssh_cli.erl
+++ b/lib/ssh/src/ssh_cli.erl
@@ -327,7 +327,7 @@ window_change(Tty, OldTty, Buf)
{[], Buf};
window_change(Tty, OldTty, {Buf, BufTail, Col}) ->
M1 = move_cursor(Col, 0, OldTty),
- N = max(Tty#ssh_pty.width - OldTty#ssh_pty.width, 0) * 2,
+ N = erlang:max(Tty#ssh_pty.width - OldTty#ssh_pty.width, 0) * 2,
S = lists:reverse(Buf, [BufTail | lists:duplicate(N, $ )]),
M2 = move_cursor(length(Buf) + length(BufTail) + N, Col, Tty),
{[M1, S | M2], {Buf, BufTail, Col}}.
@@ -398,10 +398,6 @@ nthtail(0, A) -> A;
nthtail(N, [_ | A]) when N > 0 -> nthtail(N-1, A);
nthtail(_, _) -> [].
-%%% utils
-max(A, B) when A > B -> A;
-max(_A, B) -> B.
-
ifelse(Cond, A, B) ->
case Cond of
true -> A;
diff --git a/lib/ssh/src/ssh_connect.hrl b/lib/ssh/src/ssh_connect.hrl
index 57bb141c60..34d4ff8fc1 100755
--- a/lib/ssh/src/ssh_connect.hrl
+++ b/lib/ssh/src/ssh_connect.hrl
@@ -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 b9827c90ea..7b9e9185bf 100644
--- a/lib/ssh/src/ssh_connection.erl
+++ b/lib/ssh/src/ssh_connection.erl
@@ -946,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).
%%--------------------------------------------------------------------
@@ -1017,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 990541f8d6..636ecba532 100644
--- a/lib/ssh/src/ssh_connection_controler.erl
+++ b/lib/ssh/src/ssh_connection_controler.erl
@@ -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]),
diff --git a/lib/ssh/src/ssh_connection_handler.erl b/lib/ssh/src/ssh_connection_handler.erl
index 822ef8f8f9..d46002c494 100644
--- a/lib/ssh/src/ssh_connection_handler.erl
+++ b/lib/ssh/src/ssh_connection_handler.erl
@@ -527,7 +527,7 @@ handle_info({Protocol, Socket, Data}, Statename,
%% Implementations SHOULD decrypt the length after receiving the
%% first 8 (or cipher block size, whichever is larger) bytes of a
%% packet. (RFC 4253: Section 6 - Binary Packet Protocol)
- case size(EncData0) + size(Data) >= max(8, BlockSize) of
+ case size(EncData0) + size(Data) >= erlang:max(8, BlockSize) of
true ->
{Ssh, SshPacketLen, DecData, EncData} =
@@ -758,11 +758,6 @@ after_new_keys(#state{renegotiate = false,
ssh_params = #ssh{role = server}} = State) ->
{userauth, State}.
-max(N, M) when N > M ->
- N;
-max(_, M) ->
- M.
-
handle_ssh_packet_data(RemainingSshPacketLen, DecData, EncData, StateName,
State) ->
EncSize = size(EncData),
diff --git a/lib/ssh/src/ssh_connection_manager.erl b/lib/ssh/src/ssh_connection_manager.erl
index a2effc177e..cffeade485 100644
--- a/lib/ssh/src/ssh_connection_manager.erl
+++ b/lib/ssh/src/ssh_connection_manager.erl
@@ -178,7 +178,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 +187,8 @@ init([server, _Socket, Opts]) ->
channel_id_seed = 0,
port_bindings = [],
requests = [],
- channel_pids = []},
+ channel_pids = [],
+ sub_system_supervisor = SubSysSup},
opts = Opts,
connected = false}};
@@ -400,7 +401,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,
diff --git a/lib/ssh/src/ssh_sftpd.erl b/lib/ssh/src/ssh_sftpd.erl
index dc789092dd..da91817fd7 100644
--- a/lib/ssh/src/ssh_sftpd.erl
+++ b/lib/ssh/src/ssh_sftpd.erl
@@ -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/vsn.mk b/lib/ssh/vsn.mk
index 38a82ff32d..ccdbfe4f9a 100644
--- a/lib/ssh/vsn.mk
+++ b/lib/ssh/vsn.mk
@@ -7,7 +7,9 @@ TICKETS = OTP-8524 \
OTP-8534 \
OTP-8535 \
OTP-8550 \
- OTP-8596
+ OTP-8596 \
+ OTP-8644 \
+ OTP-8645
TICKETS_1.1.8 = OTP-8356 \
OTP-8401
diff --git a/lib/ssl/doc/src/new_ssl.xml b/lib/ssl/doc/src/new_ssl.xml
index ab6e112a35..4ffaa9d96a 100644
--- a/lib/ssl/doc/src/new_ssl.xml
+++ b/lib/ssl/doc/src/new_ssl.xml
@@ -88,6 +88,10 @@
extensions are not supported yet. </item>
<item>Supported SSL/TLS-versions are SSL-3.0 and TLS-1.0 </item>
<item>For security reasons sslv2 is not supported.</item>
+ <item>Ephemeral Diffie-Hellman cipher suites are supported
+ but not Diffie Hellman Certificates cipher suites.</item>
+ <item>Export cipher suites are not supported as the
+ U.S. lifted its export restrictions in early 2000.</item>
</list>
</section>
@@ -148,25 +152,20 @@
<p><c>protocol() = sslv3 | tlsv1 </c></p>
- <p><c>ciphers() = [ciphersuite()] | sting() (according to old API)</c></p>
+ <p><c>ciphers() = [ciphersuite()] | string() (according to old API)</c></p>
<p><c>ciphersuite() =
- {key_exchange(), cipher(), hash(), exportable()}</c></p>
+ {key_exchange(), cipher(), hash()}</c></p>
- <p><c>key_exchange() = rsa | dh_dss | dh_rsa | dh_anon | dhe_dss
- | dhe_rsa | krb5 | KeyExchange_export
+ <p><c>key_exchange() = rsa | dhe_dss | dhe_rsa
</c></p>
- <p><c>cipher() = rc4_128 | idea_cbc | des_cbc | '3des_ede_cbc'
- des40_cbc | dh_dss | aes_128_cbc | aes_256_cbc |
- rc2_cbc_40 | rc4_40 </c></p>
+ <p><c>cipher() = rc4_128 | des_cbc | '3des_ede_cbc'
+ | aes_128_cbc | aes_256_cbc </c></p>
<p> <c>hash() = md5 | sha
</c></p>
- <p> <c>exportable() = export | no_export | ignore
- </c></p>
-
<p><c>ssl_imp() = new | old - default is old.</c></p>
</section>
diff --git a/lib/ssl/src/ssl.erl b/lib/ssl/src/ssl.erl
index 0ae3abfa37..185a1f755a 100644
--- a/lib/ssl/src/ssl.erl
+++ b/lib/ssl/src/ssl.erl
@@ -154,7 +154,7 @@ transport_accept(#sslsocket{pid = {ListenSocket, #config{cb=CbInfo, ssl=SslOpts}
EmOptions = emulated_options(),
{ok, InetValues} = inet:getopts(ListenSocket, EmOptions),
ok = inet:setopts(ListenSocket, internal_inet_values()),
- {CbModule,_,_} = CbInfo,
+ {CbModule,_,_, _} = CbInfo,
case CbModule:accept(ListenSocket, Timeout) of
{ok, Socket} ->
ok = inet:setopts(ListenSocket, InetValues),
@@ -216,7 +216,7 @@ ssl_accept(Socket, SslOptions, Timeout) when is_port(Socket) ->
%%
%% Description: Close a ssl connection
%%--------------------------------------------------------------------
-close(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _}}}, fd = new_ssl}) ->
+close(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _, _}}}, fd = new_ssl}) ->
CbMod:close(ListenSocket);
close(#sslsocket{pid = Pid, fd = new_ssl}) ->
ssl_connection:close(Pid);
@@ -375,7 +375,7 @@ setopts(#sslsocket{} = Socket, Options) ->
%%
%% Description: Same as gen_tcp:shutdown/2
%%--------------------------------------------------------------------
-shutdown(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _}}}, fd = new_ssl}, How) ->
+shutdown(#sslsocket{pid = {ListenSocket, #config{cb={CbMod,_, _, _}}}, fd = new_ssl}, How) ->
CbMod:shutdown(ListenSocket, How);
shutdown(#sslsocket{pid = Pid, fd = new_ssl}, How) ->
ssl_connection:shutdown(Pid, How).
@@ -449,7 +449,7 @@ do_new_connect(Address, Port,
#config{cb=CbInfo, inet_user=UserOpts, ssl=SslOpts,
emulated=EmOpts,inet_ssl=SocketOpts},
Timeout) ->
- {CbModule, _, _} = CbInfo,
+ {CbModule, _, _, _} = CbInfo,
try CbModule:connect(Address, Port, SocketOpts, Timeout) of
{ok, Socket} ->
ssl_connection:connect(Address, Port, Socket, {SslOpts,EmOpts},
@@ -471,7 +471,7 @@ old_connect(Address, Port, Options, Timeout) ->
new_listen(Port, Options0) ->
try
{ok, Config} = handle_options(Options0, server),
- #config{cb={CbModule, _, _},inet_user=Options} = Config,
+ #config{cb={CbModule, _, _, _},inet_user=Options} = Config,
case CbModule:listen(Port, Options) of
{ok, ListenSocket} ->
{ok, #sslsocket{pid = {ListenSocket, Config}, fd = new_ssl}};
@@ -546,17 +546,18 @@ handle_options(Opts0, Role) ->
%% Server side option
reuse_session = handle_option(reuse_session, Opts, ReuseSessionFun),
reuse_sessions = handle_option(reuse_sessions, Opts, true),
+ secure_renegotiate = handle_option(secure_renegotiate, Opts, false),
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}),
+ CbInfo = proplists:get_value(cb_info, Opts, {gen_tcp, tcp, tcp_closed, tcp_error}),
SslOptions = [versions, verify, verify_fun, validate_extensions_fun,
fail_if_no_peer_cert, verify_client_once,
depth, certfile, keyfile,
key, password, cacertfile, dhfile, ciphers,
debug, reuse_session, reuse_sessions, ssl_imp,
- cb_info, renegotiate_at],
+ cb_info, renegotiate_at, secure_renegotiate],
SockOpts = lists:foldl(fun(Key, PropList) ->
proplists:delete(Key, PropList)
@@ -627,6 +628,10 @@ validate_option(reuse_session, Value) when is_function(Value) ->
validate_option(reuse_sessions, Value) when Value == true;
Value == false ->
Value;
+
+validate_option(secure_renegotiate, Value) when Value == true;
+ Value == false ->
+ Value;
validate_option(renegotiate_at, Value) when is_integer(Value) ->
min(Value, ?DEFAULT_RENEGOTIATE_AT);
@@ -713,7 +718,10 @@ emulated_options([], Inet,Emulated) ->
cipher_suites(Version, []) ->
ssl_cipher:suites(Version);
-cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) ->
+cipher_suites(Version, [{_,_,_,_}| _] = Ciphers0) -> %% Backwards compatibility
+ Ciphers = [{KeyExchange, Cipher, Hash} || {KeyExchange, Cipher, Hash, _} <- Ciphers0],
+ cipher_suites(Version, Ciphers);
+cipher_suites(Version, [{_,_,_}| _] = Ciphers0) ->
Ciphers = [ssl_cipher:suite(C) || C <- Ciphers0],
cipher_suites(Version, Ciphers);
cipher_suites(Version, [Cipher0 | _] = Ciphers0) when is_binary(Cipher0) ->
@@ -735,24 +743,34 @@ cipher_suites(Version, Ciphers0) ->
format_error({error, Reason}) ->
format_error(Reason);
+format_error(Reason) when is_list(Reason) ->
+ Reason;
format_error(closed) ->
- "Connection closed for the operation in question.";
+ "The connection is closed";
+format_error(ecacertfile) ->
+ "Own CA certificate file is invalid.";
+format_error(ecertfile) ->
+ "Own certificate file is invalid.";
+format_error(ekeyfile) ->
+ "Own private key file is invalid.";
+format_error(esslaccept) ->
+ "Server SSL handshake procedure between client and server failed.";
+format_error(esslconnect) ->
+ "Client SSL handshake procedure between client and server failed.";
+format_error({eoptions, Options}) ->
+ lists:flatten(io_lib:format("Error in options list: ~p~n", [Options]));
+
+%%%%%%%%%%%% START OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
format_error(ebadsocket) ->
"Connection not found (internal error).";
format_error(ebadstate) ->
"Connection not in connect state (internal error).";
format_error(ebrokertype) ->
"Wrong broker type (internal error).";
-format_error(ecacertfile) ->
- "Own CA certificate file is invalid.";
-format_error(ecertfile) ->
- "Own certificate file is invalid.";
format_error(echaintoolong) ->
"The chain of certificates provided by peer is too long.";
format_error(ecipher) ->
"Own list of specified ciphers is invalid.";
-format_error(ekeyfile) ->
- "Own private key file is invalid.";
format_error(ekeymismatch) ->
"Own private key does not match own certificate.";
format_error(enoissuercert) ->
@@ -778,10 +796,6 @@ format_error(epeercertinvalid) ->
"Certificate provided by peer is invalid.";
format_error(eselfsignedcert) ->
"Certificate provided by peer is self signed.";
-format_error(esslaccept) ->
- "Server SSL handshake procedure between client and server failed.";
-format_error(esslconnect) ->
- "Client SSL handshake procedure between client and server failed.";
format_error(esslerrssl) ->
"SSL protocol failure. Typically because of a fatal alert from peer.";
format_error(ewantconnect) ->
@@ -800,6 +814,9 @@ format_error({badcast, _Cast}) ->
format_error({badinfo, _Info}) ->
"Call not recognized for current mode (active or passive) and state "
"of socket.";
+
+%%%%%%%%%%%%%%%%%% END OLD SSL format_error %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
format_error(Error) ->
case (catch inet:format_error(Error)) of
"unkknown POSIX" ++ _ ->
@@ -811,7 +828,7 @@ format_error(Error) ->
end.
no_format(Error) ->
- io_lib:format("No format string for error: \"~p\" available.", [Error]).
+ lists:flatten(io_lib:format("No format string for error: \"~p\" available.", [Error])).
%% Start old ssl port program if needed.
ensure_old_ssl_started() ->
diff --git a/lib/ssl/src/ssl_alert.erl b/lib/ssl/src/ssl_alert.erl
index d3f9c833f1..db9a883654 100644
--- a/lib/ssl/src/ssl_alert.erl
+++ b/lib/ssl/src/ssl_alert.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%
%%
@@ -38,10 +38,6 @@ reason_code(#alert{description = ?HANDSHAKE_FAILURE}, client) ->
esslconnect;
reason_code(#alert{description = ?HANDSHAKE_FAILURE}, server) ->
esslaccept;
-reason_code(#alert{description = ?CERTIFICATE_EXPIRED}, _) ->
- epeercertexpired;
-reason_code(#alert{level = ?FATAL}, _) ->
- esslerrssl;
reason_code(#alert{description = Description}, _) ->
description_txt(Description).
@@ -55,51 +51,51 @@ level_txt(?FATAL) ->
"Fatal error:".
description_txt(?CLOSE_NOTIFY) ->
- "close_notify";
+ "close notify";
description_txt(?UNEXPECTED_MESSAGE) ->
- "unexpected_message";
+ "unexpected message";
description_txt(?BAD_RECORD_MAC) ->
- "bad_record_mac";
+ "bad record mac";
description_txt(?DECRYPTION_FAILED) ->
- "decryption_failed";
+ "decryption failed";
description_txt(?RECORD_OVERFLOW) ->
- "record_overflow";
+ "record overflow";
description_txt(?DECOMPRESSION_FAILURE) ->
- "decompression_failure";
+ "decompression failure";
description_txt(?HANDSHAKE_FAILURE) ->
- "handshake_failure";
+ "handshake failure";
description_txt(?BAD_CERTIFICATE) ->
- "bad_certificate";
+ "bad certificate";
description_txt(?UNSUPPORTED_CERTIFICATE) ->
- "unsupported_certificate";
+ "unsupported certificate";
description_txt(?CERTIFICATE_REVOKED) ->
- "certificate_revoked";
+ "certificate revoked";
description_txt(?CERTIFICATE_EXPIRED) ->
- "certificate_expired";
+ "certificate expired";
description_txt(?CERTIFICATE_UNKNOWN) ->
- "certificate_unknown";
+ "certificate unknown";
description_txt(?ILLEGAL_PARAMETER) ->
- "illegal_parameter";
+ "illegal parameter";
description_txt(?UNKNOWN_CA) ->
- "unknown_ca";
+ "unknown ca";
description_txt(?ACCESS_DENIED) ->
- "access_denied";
+ "access denied";
description_txt(?DECODE_ERROR) ->
- "decode_error";
+ "decode error";
description_txt(?DECRYPT_ERROR) ->
- "decrypt_error";
+ "decrypt error";
description_txt(?EXPORT_RESTRICTION) ->
- "export_restriction";
+ "export restriction";
description_txt(?PROTOCOL_VERSION) ->
- "protocol_version";
+ "protocol version";
description_txt(?INSUFFICIENT_SECURITY) ->
- "insufficient_security";
+ "insufficient security";
description_txt(?INTERNAL_ERROR) ->
- "internal_error";
+ "internal error";
description_txt(?USER_CANCELED) ->
- "user_canceled";
+ "user canceled";
description_txt(?NO_RENEGOTIATION) ->
- "no_renegotiation".
+ "no renegotiation".
diff --git a/lib/ssl/src/ssl_certificate.erl b/lib/ssl/src/ssl_certificate.erl
index 686e90a70c..37d5646673 100644
--- a/lib/ssl/src/ssl_certificate.erl
+++ b/lib/ssl/src/ssl_certificate.erl
@@ -67,7 +67,7 @@ trusted_cert_and_path(CertChain, CertDbRef, Verify) ->
%% The root CA was not sent and can not be found, we fail if verify = true
not_valid(?ALERT_REC(?FATAL, ?UNKNOWN_CA), Verify, {Cert, RestPath});
{{SerialNr, Issuer}, Path} ->
- case ssl_certificate_db:lookup_trusted_cert(CertDbRef,
+ case ssl_manager:lookup_trusted_cert(CertDbRef,
SerialNr, Issuer) of
{ok, {BinCert,_}} ->
{BinCert, Path, []};
@@ -85,7 +85,7 @@ certificate_chain(OwnCert, CertsDbRef) ->
{ok, ErlCert} = public_key:pkix_decode_cert(OwnCert, otp),
certificate_chain(ErlCert, OwnCert, CertsDbRef, [OwnCert]).
-file_to_certificats(File) ->
+file_to_certificats(File) ->
{ok, List} = ssl_manager:cache_pem_file(File),
[Bin || {cert, Bin, not_encrypted} <- List].
@@ -148,7 +148,7 @@ certificate_chain(_CertsDbRef, Chain, _SerialNr, _Issuer, true) ->
{ok, lists:reverse(Chain)};
certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) ->
- case ssl_certificate_db:lookup_trusted_cert(CertsDbRef,
+ case ssl_manager:lookup_trusted_cert(CertsDbRef,
SerialNr, Issuer) of
{ok, {IssuerCert, ErlCert}} ->
{ok, ErlCert} = public_key:pkix_decode_cert(IssuerCert, otp),
@@ -164,7 +164,7 @@ certificate_chain(CertsDbRef, Chain, SerialNr, Issuer, _SelfSigned) ->
end.
find_issuer(OtpCert, PrevCandidateKey) ->
- case ssl_certificate_db:issuer_candidate(PrevCandidateKey) of
+ case ssl_manager:issuer_candidate(PrevCandidateKey) of
no_more_candidates ->
{error, issuer_not_found};
{Key, {_Cert, ErlCertCandidate}} ->
diff --git a/lib/ssl/src/ssl_cipher.erl b/lib/ssl/src/ssl_cipher.erl
index 3d3d11b7f3..f425886ce5 100644
--- a/lib/ssl/src/ssl_cipher.erl
+++ b/lib/ssl/src/ssl_cipher.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,10 +28,11 @@
-include("ssl_internal.hrl").
-include("ssl_record.hrl").
-include("ssl_cipher.hrl").
+-include("ssl_alert.hrl").
-include("ssl_debug.hrl").
-export([security_parameters/2, suite_definition/1,
- decipher/4, cipher/4,
+ decipher/5, cipher/4,
suite/1, suites/1,
openssl_suite/1, openssl_suite_name/1]).
@@ -48,7 +49,7 @@
%% cipher values has been updated according to <CipherSuite>
%%-------------------------------------------------------------------
security_parameters(CipherSuite, SecParams) ->
- { _, Cipher, Hash, Exportable} = suite_definition(CipherSuite),
+ { _, Cipher, Hash} = suite_definition(CipherSuite),
SecParams#security_parameters{
cipher_suite = CipherSuite,
bulk_cipher_algorithm = bulk_cipher_algorithm(Cipher),
@@ -58,8 +59,7 @@ security_parameters(CipherSuite, SecParams) ->
key_material_length = key_material(Cipher),
iv_size = iv_size(Cipher),
mac_algorithm = mac_algorithm(Hash),
- hash_size = hash_size(Hash),
- exportable = Exportable}.
+ hash_size = hash_size(Hash)}.
%%--------------------------------------------------------------------
%% Function: cipher(Method, CipherState, Mac, Data) ->
@@ -91,10 +91,10 @@ cipher(?DES, CipherState, Mac, Fragment) ->
block_cipher(fun(Key, IV, T) ->
crypto:des_cbc_encrypt(Key, IV, T)
end, block_size(des_cbc), CipherState, Mac, Fragment);
-cipher(?DES40, CipherState, Mac, Fragment) ->
- block_cipher(fun(Key, IV, T) ->
- crypto:des_cbc_encrypt(Key, IV, T)
- end, block_size(des_cbc), CipherState, Mac, Fragment);
+%% cipher(?DES40, CipherState, Mac, Fragment) ->
+%% block_cipher(fun(Key, IV, T) ->
+%% crypto:des_cbc_encrypt(Key, IV, T)
+%% end, block_size(des_cbc), CipherState, Mac, Fragment);
cipher(?'3DES', CipherState, Mac, Fragment) ->
block_cipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) ->
crypto:des3_cbc_encrypt(K1, K2, K3, IV, T)
@@ -104,15 +104,11 @@ cipher(?AES, CipherState, Mac, Fragment) ->
crypto:aes_cbc_128_encrypt(Key, IV, T);
(Key, IV, T) when byte_size(Key) =:= 32 ->
crypto:aes_cbc_256_encrypt(Key, IV, T)
- end, block_size(aes_128_cbc), CipherState, Mac, Fragment);
+ end, block_size(aes_128_cbc), CipherState, Mac, Fragment).
%% cipher(?IDEA, CipherState, Mac, Fragment) ->
%% block_cipher(fun(Key, IV, T) ->
%% crypto:idea_cbc_encrypt(Key, IV, T)
%% end, block_size(idea_cbc), CipherState, Mac, Fragment);
-cipher(?RC2, CipherState, Mac, Fragment) ->
- block_cipher(fun(Key, IV, T) ->
- crypto:rc2_40_cbc_encrypt(Key, IV, T)
- end, block_size(rc2_cbc_40), CipherState, Mac, Fragment).
block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
Mac, Fragment) ->
@@ -128,7 +124,7 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
{T, CS0#cipher_state{iv=NextIV}}.
%%--------------------------------------------------------------------
-%% Function: decipher(Method, CipherState, Mac, Data) ->
+%% Function: decipher(Method, CipherState, Mac, Data, Version) ->
%% {Decrypted, UpdateCipherState}
%%
%% Method - integer() (as defined in ssl_cipher.hrl)
@@ -138,9 +134,9 @@ block_cipher(Fun, BlockSz, #cipher_state{key=Key, iv=IV} = CS0,
%% Description: Decrypts the data and the mac using method, updating
%% the cipher state
%%-------------------------------------------------------------------
-decipher(?NULL, _HashSz, CipherState, Fragment) ->
+decipher(?NULL, _HashSz, CipherState, Fragment, _) ->
{Fragment, <<>>, CipherState};
-decipher(?RC4, HashSz, CipherState, Fragment) ->
+decipher(?RC4, HashSz, CipherState, Fragment, _) ->
?DBG_TERM(CipherState#cipher_state.key),
State0 = case CipherState#cipher_state.state of
undefined -> crypto:rc4_set_key(CipherState#cipher_state.key);
@@ -153,47 +149,47 @@ decipher(?RC4, HashSz, CipherState, Fragment) ->
GSC = generic_stream_cipher_from_bin(T, HashSz),
#generic_stream_cipher{content=Content, mac=Mac} = GSC,
{Content, Mac, CipherState#cipher_state{state=State1}};
-decipher(?DES, HashSz, CipherState, Fragment) ->
- block_decipher(fun(Key, IV, T) ->
- crypto:des_cbc_decrypt(Key, IV, T)
- end, CipherState, HashSz, Fragment);
-decipher(?DES40, HashSz, CipherState, Fragment) ->
+decipher(?DES, HashSz, CipherState, Fragment, Version) ->
block_decipher(fun(Key, IV, T) ->
crypto:des_cbc_decrypt(Key, IV, T)
- end, CipherState, HashSz, Fragment);
-decipher(?'3DES', HashSz, CipherState, Fragment) ->
+ end, CipherState, HashSz, Fragment, Version);
+%% decipher(?DES40, HashSz, CipherState, Fragment, Version) ->
+%% block_decipher(fun(Key, IV, T) ->
+%% crypto:des_cbc_decrypt(Key, IV, T)
+%% end, CipherState, HashSz, Fragment, Version);
+decipher(?'3DES', HashSz, CipherState, Fragment, Version) ->
block_decipher(fun(<<K1:8/binary, K2:8/binary, K3:8/binary>>, IV, T) ->
crypto:des3_cbc_decrypt(K1, K2, K3, IV, T)
- end, CipherState, HashSz, Fragment);
-decipher(?AES, HashSz, CipherState, Fragment) ->
+ end, CipherState, HashSz, Fragment, Version);
+decipher(?AES, HashSz, CipherState, Fragment, Version) ->
block_decipher(fun(Key, IV, T) when byte_size(Key) =:= 16 ->
crypto:aes_cbc_128_decrypt(Key, IV, T);
(Key, IV, T) when byte_size(Key) =:= 32 ->
crypto:aes_cbc_256_decrypt(Key, IV, T)
- end, CipherState, HashSz, Fragment);
-%% decipher(?IDEA, HashSz, CipherState, Fragment) ->
+ end, CipherState, HashSz, Fragment, Version).
+%% decipher(?IDEA, HashSz, CipherState, Fragment, Version) ->
%% block_decipher(fun(Key, IV, T) ->
%% crypto:idea_cbc_decrypt(Key, IV, T)
-%% end, CipherState, HashSz, Fragment);
-decipher(?RC2, HashSz, CipherState, Fragment) ->
- block_decipher(fun(Key, IV, T) ->
- crypto:rc2_40_cbc_decrypt(Key, IV, T)
- end, CipherState, HashSz, Fragment).
+%% end, CipherState, HashSz, Fragment, Version);
block_decipher(Fun, #cipher_state{key=Key, iv=IV} = CipherState0,
- HashSz, Fragment) ->
+ HashSz, Fragment, Version) ->
?DBG_HEX(Key),
?DBG_HEX(IV),
?DBG_HEX(Fragment),
T = Fun(Key, IV, Fragment),
?DBG_HEX(T),
GBC = generic_block_cipher_from_bin(T, HashSz),
- ok = check_padding(GBC), %% TODO kolla ocks�...
- Content = GBC#generic_block_cipher.content,
- Mac = GBC#generic_block_cipher.mac,
- CipherState1 = CipherState0#cipher_state{iv=next_iv(Fragment, IV)},
- {Content, Mac, CipherState1}.
-
+ case is_correct_padding(GBC, Version) of
+ true ->
+ Content = GBC#generic_block_cipher.content,
+ Mac = GBC#generic_block_cipher.mac,
+ CipherState1 = CipherState0#cipher_state{iv=next_iv(Fragment, IV)},
+ {Content, Mac, CipherState1};
+ false ->
+ ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+ end.
+
%%--------------------------------------------------------------------
%% Function: suites(Version) -> [Suite]
%%
@@ -209,289 +205,147 @@ suites({3, N}) when N == 1; N == 2 ->
%%--------------------------------------------------------------------
%% Function: suite_definition(CipherSuite) ->
-%% {KeyExchange, Cipher, Hash, Exportable}
+%% {KeyExchange, Cipher, Hash}
%%
%%
%% CipherSuite - as defined in ssl_cipher.hrl
-%% KeyExchange - rsa | dh_dss | dh_rsa | dh_anon | dhe_dss | dhe_rsa
-%% krb5 | *_export (old ssl)
+%% KeyExchange - rsa | dh_anon | dhe_dss | dhe_rsa | kerb5
+%%
%% Cipher - null | rc4_128 | idea_cbc | des_cbc | '3des_ede_cbc'
-%% des40_cbc | dh_dss | aes_128_cbc | aes_256_cbc |
-%% rc2_cbc_40 | rc4_40
+%% des40_cbc | aes_128_cbc | aes_256_cbc
%% Hash - null | md5 | sha
-%% Exportable - export | no_export | ignore(?)
%%
-%% Description: Returns a security parameters record where the
+%% Description: Returns a security parameters tuple where the
%% cipher values has been updated according to <CipherSuite>
-%% Note: since idea is unsupported on the openssl version used by
-%% crypto (as of OTP R12B), we've commented away the idea stuff
+%% Note: Currently not supported suites are commented away.
+%% They should be supported or removed in the future.
%%-------------------------------------------------------------------
%% TLS v1.1 suites
suite_definition(?TLS_NULL_WITH_NULL_NULL) ->
- {null, null, null, ignore};
-suite_definition(?TLS_RSA_WITH_NULL_MD5) ->
- {rsa, null, md5, ignore};
-suite_definition(?TLS_RSA_WITH_NULL_SHA) ->
- {rsa, null, sha, ignore};
-suite_definition(?TLS_RSA_WITH_RC4_128_MD5) -> % ok
- {rsa, rc4_128, md5, no_export};
-suite_definition(?TLS_RSA_WITH_RC4_128_SHA) -> % ok
- {rsa, rc4_128, sha, no_export};
-%% suite_definition(?TLS_RSA_WITH_IDEA_CBC_SHA) -> % unsupported
-%% {rsa, idea_cbc, sha, no_export};
-suite_definition(?TLS_RSA_WITH_DES_CBC_SHA) -> % ok
- {rsa, des_cbc, sha, no_export};
+ {null, null, null};
+%% suite_definition(?TLS_RSA_WITH_NULL_MD5) ->
+%% {rsa, null, md5};
+%% suite_definition(?TLS_RSA_WITH_NULL_SHA) ->
+%% {rsa, null, sha};
+suite_definition(?TLS_RSA_WITH_RC4_128_MD5) ->
+ {rsa, rc4_128, md5};
+suite_definition(?TLS_RSA_WITH_RC4_128_SHA) ->
+ {rsa, rc4_128, sha};
+%% suite_definition(?TLS_RSA_WITH_IDEA_CBC_SHA) ->
+%% {rsa, idea_cbc, sha};
+suite_definition(?TLS_RSA_WITH_DES_CBC_SHA) ->
+ {rsa, des_cbc, sha};
suite_definition(?TLS_RSA_WITH_3DES_EDE_CBC_SHA) ->
- {rsa, '3des_ede_cbc', sha, no_export};
-suite_definition(?TLS_DH_DSS_WITH_DES_CBC_SHA) ->
- {dh_dss, des_cbc, sha, no_export};
-suite_definition(?TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA) ->
- {dh_dss, '3des_ede_cbc', sha, no_export};
-suite_definition(?TLS_DH_RSA_WITH_DES_CBC_SHA) ->
- {dh_rsa, des_cbc, sha, no_export};
-suite_definition(?TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA) ->
- {dh_rsa, '3des_ede_cbc', sha, no_export};
+ {rsa, '3des_ede_cbc', sha};
suite_definition(?TLS_DHE_DSS_WITH_DES_CBC_SHA) ->
- {dhe_dss, des_cbc, sha, no_export};
+ {dhe_dss, des_cbc, sha};
suite_definition(?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA) ->
- {dhe_dss, '3des_ede_cbc', sha, no_export};
+ {dhe_dss, '3des_ede_cbc'};
suite_definition(?TLS_DHE_RSA_WITH_DES_CBC_SHA) ->
- {dhe_rsa, des_cbc, sha, no_export};
+ {dhe_rsa, des_cbc, sha};
suite_definition(?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA) ->
- {dhe_rsa, '3des_ede_cbc', sha, no_export};
-suite_definition(?TLS_DH_anon_WITH_RC4_128_MD5) ->
- {dh_anon, rc4_128, md5, no_export};
-suite_definition(?TLS_DH_anon_WITH_DES_CBC_SHA) ->
- {dh_anon, des40_cbc, sha, no_export};
-suite_definition(?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA) ->
- {dh_anon, '3des_ede_cbc', sha, no_export};
+ {dhe_rsa, '3des_ede_cbc', sha};
%%% TSL V1.1 AES suites
-suite_definition(?TLS_RSA_WITH_AES_128_CBC_SHA) -> % ok
- {rsa, aes_128_cbc, sha, ignore};
-suite_definition(?TLS_DH_DSS_WITH_AES_128_CBC_SHA) ->
- {dh_dss, aes_128_cbc, sha, ignore};
-suite_definition(?TLS_DH_RSA_WITH_AES_128_CBC_SHA) ->
- {dh_rsa, aes_128_cbc, sha, ignore};
+suite_definition(?TLS_RSA_WITH_AES_128_CBC_SHA) ->
+ {rsa, aes_128_cbc, sha};
suite_definition(?TLS_DHE_DSS_WITH_AES_128_CBC_SHA) ->
- {dhe_dss, aes_128_cbc, sha, ignore};
+ {dhe_dss, aes_128_cbc, sha};
suite_definition(?TLS_DHE_RSA_WITH_AES_128_CBC_SHA) ->
- {dhe_rsa, aes_128_cbc, sha, ignore};
-suite_definition(?TLS_DH_anon_WITH_AES_128_CBC_SHA) ->
- {dh_anon, aes_128_cbc, sha, ignore};
-suite_definition(?TLS_RSA_WITH_AES_256_CBC_SHA) -> % ok
- {rsa, aes_256_cbc, sha, ignore};
-suite_definition(?TLS_DH_DSS_WITH_AES_256_CBC_SHA) ->
- {dh_dss, aes_256_cbc, sha, ignore};
-suite_definition(?TLS_DH_RSA_WITH_AES_256_CBC_SHA) ->
- {dh_rsa, aes_256_cbc, sha, ignore};
+ {dhe_rsa, aes_128_cbc, sha};
+suite_definition(?TLS_RSA_WITH_AES_256_CBC_SHA) ->
+ {rsa, aes_256_cbc, sha};
suite_definition(?TLS_DHE_DSS_WITH_AES_256_CBC_SHA) ->
- {dhe_dss, aes_256_cbc, sha, ignore};
+ {dhe_dss, aes_256_cbc, sha};
suite_definition(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) ->
- {dhe_rsa, aes_256_cbc, sha, ignore};
-suite_definition(?TLS_DH_anon_WITH_AES_256_CBC_SHA) ->
- {dh_anon, aes_256_cbc, sha, ignore};
-
-%% TSL V1.1 KRB SUITES
-suite_definition(?TLS_KRB5_WITH_DES_CBC_SHA) ->
- {krb5, des_cbc, sha, ignore};
-suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_SHA) ->
- {krb5, '3des_ede_cbc', sha, ignore};
-suite_definition(?TLS_KRB5_WITH_RC4_128_SHA) ->
- {krb5, rc4_128, sha, ignore};
+ {dhe_rsa, aes_256_cbc, sha}.
+
+%% TODO: support kerbos key exchange?
+%% TSL V1.1 KRB SUITES
+%% suite_definition(?TLS_KRB5_WITH_DES_CBC_SHA) ->
+%% {krb5, des_cbc, sha};
+%% suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_SHA) ->
+%% {krb5, '3des_ede_cbc', sha};
+%% suite_definition(?TLS_KRB5_WITH_RC4_128_SHA) ->
+%% {krb5, rc4_128, sha};
%% suite_definition(?TLS_KRB5_WITH_IDEA_CBC_SHA) ->
-%% {krb5, idea_cbc, sha, ignore};
-suite_definition(?TLS_KRB5_WITH_DES_CBC_MD5) ->
- {krb5, des_cbc, md5, ignore};
-suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_MD5) ->
- {krb5, '3des_ede_cbc', md5, ignore};
-suite_definition(?TLS_KRB5_WITH_RC4_128_MD5) ->
- {krb5, rc4_128, md5, ignore};
+%% {krb5, idea_cbc, sha};
+%% suite_definition(?TLS_KRB5_WITH_DES_CBC_MD5) ->
+%% {krb5, des_cbc, md5};
+%% suite_definition(?TLS_KRB5_WITH_3DES_EDE_CBC_MD5) ->
+%% {krb5, '3des_ede_cbc', md5};
+%% suite_definition(?TLS_KRB5_WITH_RC4_128_MD5) ->
+%% {krb5, rc4_128, md5};
%% suite_definition(?TLS_KRB5_WITH_IDEA_CBC_MD5) ->
-%% {krb5, idea_cbc, md5, ignore};
-
-suite_definition(?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5) ->
- {rsa, rc4_56, md5, export};
-suite_definition(?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5) ->
- {rsa, rc2_cbc_56, md5, export};
-suite_definition(?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA) ->
- {rsa, des_cbc, sha, export};
-suite_definition(?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA) ->
- {dhe_dss, des_cbc, sha, export};
-suite_definition(?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA) ->
- {rsa, rc4_56, sha, export};
-suite_definition(?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA) ->
- {dhe_dss, rc4_56, sha, export};
-suite_definition(?TLS_DHE_DSS_WITH_RC4_128_SHA) ->
- {dhe_dss, rc4_128, sha, export};
-
-%% Export suites TLS 1.0 OR SSLv3-only servers.
-suite_definition(?TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA) ->
- {krb5_export, des40_cbc, sha, export};
-suite_definition(?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA) ->
- {krb5_export, rc2_cbc_40, sha, export};
-suite_definition(?TLS_KRB5_EXPORT_WITH_RC4_40_SHA) ->
- {krb5_export, des40_cbc, sha, export};
-suite_definition(?TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5) ->
- {krb5_export, des40_cbc, md5, export};
-suite_definition(?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5) ->
- {krb5_export, rc2_cbc_40, md5, export};
-suite_definition(?TLS_KRB5_EXPORT_WITH_RC4_40_MD5) ->
- {krb5_export, rc2_cbc_40, md5, export};
-suite_definition(?TLS_RSA_EXPORT_WITH_RC4_40_MD5) -> % ok
- {rsa, rc4_40, md5, export};
-suite_definition(?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5) -> % ok
- {rsa, rc2_cbc_40, md5, export};
-suite_definition(?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
- {rsa, des40_cbc, sha, export};
-suite_definition(?TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA) ->
- {dh_dss, des40_cbc, sha, export};
-suite_definition(?TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
- {dh_rsa, des40_cbc, sha, export};
-suite_definition(?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA) ->
- {dhe_dss, des40_cbc, sha, export};
-suite_definition(?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
- {dhe_rsa, des40_cbc, sha, export};
-suite_definition(?TLS_DH_anon_EXPORT_WITH_RC4_40_MD5) ->
- {dh_anon, rc4_40, md5, export};
-suite_definition(?TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA) ->
- {dh_anon, des40_cbc, sha, export}.
+%% {krb5, idea_cbc, md5};
%% TLS v1.1 suites
-suite({rsa, null, md5, ignore}) ->
- ?TLS_RSA_WITH_NULL_MD5;
-suite({rsa, null, sha, ignore}) ->
- ?TLS_RSA_WITH_NULL_SHA;
-suite({rsa, rc4_128, md5, no_export}) ->
+%%suite({rsa, null, md5}) ->
+%% ?TLS_RSA_WITH_NULL_MD5;
+%%suite({rsa, null, sha}) ->
+%% ?TLS_RSA_WITH_NULL_SHA;
+suite({rsa, rc4_128, md5}) ->
?TLS_RSA_WITH_RC4_128_MD5;
-suite({rsa, rc4_128, sha, no_export}) ->
+suite({rsa, rc4_128, sha}) ->
?TLS_RSA_WITH_RC4_128_SHA;
-%% suite({rsa, idea_cbc, sha, no_export}) ->
+%% suite({rsa, idea_cbc, sha}) ->
%% ?TLS_RSA_WITH_IDEA_CBC_SHA;
-suite({rsa, des_cbc, sha, no_export}) ->
+suite({rsa, des_cbc, sha}) ->
?TLS_RSA_WITH_DES_CBC_SHA;
-suite({rsa, '3des_ede_cbc', sha, no_export}) ->
+suite({rsa, '3des_ede_cbc', sha}) ->
?TLS_RSA_WITH_3DES_EDE_CBC_SHA;
-suite({dh_dss, des_cbc, sha, no_export}) ->
- ?TLS_DH_DSS_WITH_DES_CBC_SHA;
-suite({dh_dss, '3des_ede_cbc', sha, no_export}) ->
- ?TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA;
-suite({dh_rsa, des_cbc, sha, no_export}) ->
- ?TLS_DH_RSA_WITH_DES_CBC_SHA;
-suite({dh_rsa, '3des_ede_cbc', sha, no_export}) ->
- ?TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA;
-suite({dhe_dss, des_cbc, sha, no_export}) ->
+suite({dhe_dss, des_cbc, sha}) ->
?TLS_DHE_DSS_WITH_DES_CBC_SHA;
-suite({dhe_dss, '3des_ede_cbc', sha, no_export}) ->
+suite({dhe_dss, '3des_ede_cbc', sha}) ->
?TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA;
-suite({dhe_rsa, des_cbc, sha, no_export}) ->
+suite({dhe_rsa, des_cbc, sha}) ->
?TLS_DHE_RSA_WITH_DES_CBC_SHA;
-suite({dhe_rsa, '3des_ede_cbc', sha, no_export}) ->
+suite({dhe_rsa, '3des_ede_cbc', sha}) ->
?TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA;
-suite({dh_anon, rc4_128, md5, no_export}) ->
- ?TLS_DH_anon_WITH_RC4_128_MD5;
-suite({dh_anon, des40_cbc, sha, no_export}) ->
- ?TLS_DH_anon_WITH_DES_CBC_SHA;
-suite({dh_anon, '3des_ede_cbc', sha, no_export}) ->
- ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
+%% suite({dh_anon, rc4_128, md5}) ->
+%% ?TLS_DH_anon_WITH_RC4_128_MD5;
+%% suite({dh_anon, des40_cbc, sha}) ->
+%% ?TLS_DH_anon_WITH_DES_CBC_SHA;
+%% suite({dh_anon, '3des_ede_cbc', sha}) ->
+%% ?TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
%%% TSL V1.1 AES suites
-suite({rsa, aes_128_cbc, sha, ignore}) ->
+suite({rsa, aes_128_cbc, sha}) ->
?TLS_RSA_WITH_AES_128_CBC_SHA;
-suite({dh_dss, aes_128_cbc, sha, ignore}) ->
- ?TLS_DH_DSS_WITH_AES_128_CBC_SHA;
-suite({dh_rsa, aes_128_cbc, sha, ignore}) ->
- ?TLS_DH_RSA_WITH_AES_128_CBC_SHA;
-suite({dhe_dss, aes_128_cbc, sha, ignore}) ->
- ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
-suite({dhe_rsa, aes_128_cbc, sha, ignore}) ->
+%% suite({dhe_dss, aes_128_cbc, sha}) ->
+%% ?TLS_DHE_DSS_WITH_AES_128_CBC_SHA;
+suite({dhe_rsa, aes_128_cbc, sha}) ->
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA;
-suite({dh_anon, aes_128_cbc, sha, ignore}) ->
- ?TLS_DH_anon_WITH_AES_128_CBC_SHA;
-suite({rsa, aes_256_cbc, sha, ignore}) ->
+%% suite({dh_anon, aes_128_cbc, sha}) ->
+%% ?TLS_DH_anon_WITH_AES_128_CBC_SHA;
+suite({rsa, aes_256_cbc, sha}) ->
?TLS_RSA_WITH_AES_256_CBC_SHA;
-suite({dh_dss, aes_256_cbc, sha, ignore}) ->
- ?TLS_DH_DSS_WITH_AES_256_CBC_SHA;
-suite({dh_rsa, aes_256_cbc, sha, ignore}) ->
- ?TLS_DH_RSA_WITH_AES_256_CBC_SHA;
-suite({dhe_dss, aes_256_cbc, sha, ignore}) ->
+suite({dhe_dss, aes_256_cbc, sha}) ->
?TLS_DHE_DSS_WITH_AES_256_CBC_SHA;
-suite({dhe_rsa, aes_256_cbc, sha, ignore}) ->
- ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA;
-suite({dh_anon, aes_256_cbc, sha, ignore}) ->
- ?TLS_DH_anon_WITH_AES_256_CBC_SHA;
+suite({dhe_rsa, aes_256_cbc, sha}) ->
+ ?TLS_DHE_RSA_WITH_AES_256_CBC_SHA.
+%% suite({dh_anon, aes_256_cbc, sha}) ->
+%% ?TLS_DH_anon_WITH_AES_256_CBC_SHA.
+%% TODO: support kerbos key exchange?
%% TSL V1.1 KRB SUITES
-suite({krb5, des_cbc, sha, ignore}) ->
- ?TLS_KRB5_WITH_DES_CBC_SHA;
-suite({krb5_cbc, '3des_ede_cbc', sha, ignore}) ->
- ?TLS_KRB5_WITH_3DES_EDE_CBC_SHA;
-suite({krb5, rc4_128, sha, ignore}) ->
- ?TLS_KRB5_WITH_RC4_128_SHA;
-%% suite({krb5_cbc, idea_cbc, sha, ignore}) ->
+%% suite({krb5, des_cbc, sha}) ->
+%% ?TLS_KRB5_WITH_DES_CBC_SHA;
+%% suite({krb5_cbc, '3des_ede_cbc', sha}) ->
+%% ?TLS_KRB5_WITH_3DES_EDE_CBC_SHA;
+%% suite({krb5, rc4_128, sha}) ->
+%% ?TLS_KRB5_WITH_RC4_128_SHA;
+%% suite({krb5_cbc, idea_cbc, sha}) ->
%% ?TLS_KRB5_WITH_IDEA_CBC_SHA;
-suite({krb5_cbc, md5, ignore}) ->
- ?TLS_KRB5_WITH_DES_CBC_MD5;
-suite({krb5_ede_cbc, des_cbc, md5, ignore}) ->
- ?TLS_KRB5_WITH_3DES_EDE_CBC_MD5;
-suite({krb5_128, rc4_128, md5, ignore}) ->
- ?TLS_KRB5_WITH_RC4_128_MD5;
-%% suite({krb5, idea_cbc, md5, ignore}) ->
+%% suite({krb5_cbc, md5}) ->
+%% ?TLS_KRB5_WITH_DES_CBC_MD5;
+%% suite({krb5_ede_cbc, des_cbc, md5}) ->
+%% ?TLS_KRB5_WITH_3DES_EDE_CBC_MD5;
+%% suite({krb5_128, rc4_128, md5}) ->
+%% ?TLS_KRB5_WITH_RC4_128_MD5;
+%% suite({krb5, idea_cbc, md5}) ->
%% ?TLS_KRB5_WITH_IDEA_CBC_MD5;
-%% Export suites TLS 1.0 OR SSLv3-only servers.
-suite({rsa, rc4_40, md5, export}) ->
- ?TLS_RSA_EXPORT_WITH_RC4_40_MD5;
-suite({rsa, rc2_cbc_40, md5, export}) ->
- ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
-suite({rsa, des40_cbc, sha, export}) ->
- ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
-suite({rsa, rc4_56, md5, export}) ->
- ?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5;
-suite({rsa, rc2_cbc_56, md5, export}) ->
- ?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5;
-suite({rsa, des_cbc, sha, export}) ->
- ?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA;
-suite({dhe_dss, des_cbc, sha, export}) ->
- ?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA;
-suite({rsa, rc4_56, sha, export}) ->
- ?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA;
-suite({dhe_dss, rc4_56, sha, export}) ->
- ?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA;
-suite({dhe_dss, rc4_128, sha, export}) ->
- ?TLS_DHE_DSS_WITH_RC4_128_SHA;
-suite({krb5_export, des40_cbc, sha, export}) ->
- ?TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA;
-suite({krb5_export, rc2_cbc_40, sha, export}) ->
- ?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA;
-suite({krb5_export, rc4_cbc_40, sha, export}) ->
- ?TLS_KRB5_EXPORT_WITH_RC4_40_SHA;
-suite({krb5_export, des40_cbc, md5, export}) ->
- ?TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5;
-suite({krb5_export, rc2_cbc_40, md5, export}) ->
- ?TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5;
-suite({krb5_export, rc4_cbc_40, md5, export}) ->
- ?TLS_KRB5_EXPORT_WITH_RC4_40_MD5;
-suite({rsa_export, rc4_cbc_40, md5, export}) ->
- ?TLS_RSA_EXPORT_WITH_RC4_40_MD5;
-suite({rsa_export, rc2_cbc_40, md5, export}) ->
- ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
-suite({rsa_export, des40_cbc, sha, export}) ->
- ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
-suite({dh_dss_export, des40_cbc, sha, export}) ->
- ?TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA;
-suite({dh_rsa_export, des40_cbc, sha, export}) ->
- ?TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA;
-suite({dhe_dss_export, des40_cbc, sha, export}) ->
- ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
-suite({dhe_rsa_export, des40_cbc, sha, export}) ->
- ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
-suite({dh_anon_export, rc4_40, md5, export}) ->
- ?TLS_DH_anon_EXPORT_WITH_RC4_40_MD5;
-suite({dh_anon_export, des40_cbc, sha, export}) ->
- ?TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA.
-
-
%% translate constants <-> openssl-strings
%% TODO: Is there a pattern in the nameing
%% that is useable to make a nicer function defention?
@@ -523,36 +377,12 @@ openssl_suite("RC4-SHA") ->
?TLS_RSA_WITH_RC4_128_SHA;
openssl_suite("RC4-MD5") ->
?TLS_RSA_WITH_RC4_128_MD5;
-%% TODO: Do we want to support this?
-openssl_suite("EXP1024-RC4-MD5") ->
- ?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5;
-openssl_suite("EXP1024-RC2-CBC-MD5") ->
- ?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5;
-openssl_suite("EXP1024-DES-CBC-SHA") ->
- ?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA;
-openssl_suite("EXP1024-DHE-DSS-DES-CBC-SHA") ->
- ?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA;
-openssl_suite("EXP1024-RC4-SHA") ->
- ?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA;
-openssl_suite("EXP1024-DHE-DSS-RC4-SHA") ->
- ?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA;
-openssl_suite("DHE-DSS-RC4-SHA") ->
- ?TLS_DHE_DSS_WITH_RC4_128_SHA;
-
+%% openssl_suite("DHE-DSS-RC4-SHA") ->
+%% ?TLS_DHE_DSS_WITH_RC4_128_SHA;
openssl_suite("EDH-RSA-DES-CBC-SHA") ->
?TLS_DHE_RSA_WITH_DES_CBC_SHA;
openssl_suite("DES-CBC-SHA") ->
- ?TLS_RSA_WITH_DES_CBC_SHA;
-openssl_suite("EXP-EDH-RSA-DES-CBC-SHA") ->
- ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA;
-openssl_suite("EXP-EDH-DSS-DES-CBC-SHA") ->
- ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA;
-openssl_suite("EXP-DES-CBC-SHA") ->
- ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA;
-openssl_suite("EXP-RC2-CBC-MD5") ->
- ?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5;
-openssl_suite("EXP-RC4-MD5") ->
- ?TLS_RSA_EXPORT_WITH_RC4_40_MD5.
+ ?TLS_RSA_WITH_DES_CBC_SHA.
openssl_suite_name(?TLS_DHE_RSA_WITH_AES_256_CBC_SHA) ->
"DHE-RSA-AES256-SHA";
@@ -582,31 +412,9 @@ openssl_suite_name(?TLS_DHE_RSA_WITH_DES_CBC_SHA) ->
"EDH-RSA-DES-CBC-SHA";
openssl_suite_name(?TLS_RSA_WITH_DES_CBC_SHA) ->
"DES-CBC-SHA";
-openssl_suite_name(?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
- "EXP-EDH-RSA-DES-CBC-SHA";
-openssl_suite_name(?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA) ->
- "EXP-EDH-DSS-DES-CBC-SHA";
-openssl_suite_name(?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA) ->
- "EXP-DES-CBC-SHA";
-openssl_suite_name(?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5) ->
- "EXP-RC2-CBC-MD5";
-openssl_suite_name(?TLS_RSA_EXPORT_WITH_RC4_40_MD5) ->
- "EXP-RC4-MD5";
-
-openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5) ->
- "EXP1024-RC4-MD5";
-openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5) ->
- "EXP1024-RC2-CBC-MD5";
-openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA) ->
- "EXP1024-DES-CBC-SHA";
-openssl_suite_name(?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA) ->
- "EXP1024-DHE-DSS-DES-CBC-SHA";
-openssl_suite_name(?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA) ->
- "EXP1024-RC4-SHA";
-openssl_suite_name(?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA) ->
- "EXP1024-DHE-DSS-RC4-SHA";
-openssl_suite_name(?TLS_DHE_DSS_WITH_RC4_128_SHA) ->
- "DHE-DSS-RC4-SHA";
+
+%% openssl_suite_name(?TLS_DHE_DSS_WITH_RC4_128_SHA) ->
+%% "DHE-DSS-RC4-SHA";
%% No oppenssl name
openssl_suite_name(Cipher) ->
@@ -621,15 +429,10 @@ bulk_cipher_algorithm(null) ->
%% Not supported yet
%% bulk_cipher_algorithm(idea_cbc) ->
%% ?IDEA;
-bulk_cipher_algorithm(Cipher) when Cipher == rc2_cbc_40;
- Cipher == rc2_cbc_56 ->
- ?RC2;
-bulk_cipher_algorithm(Cipher) when Cipher == rc4_40;
- Cipher == rc4_56;
- Cipher == rc4_128 ->
+bulk_cipher_algorithm(rc4_128) ->
?RC4;
-bulk_cipher_algorithm(des40_cbc) ->
- ?DES40;
+%% bulk_cipher_algorithm(des40_cbc) ->
+%% ?DES40;
bulk_cipher_algorithm(des_cbc) ->
?DES;
bulk_cipher_algorithm('3des_ede_cbc') ->
@@ -639,14 +442,10 @@ bulk_cipher_algorithm(Cipher) when Cipher == aes_128_cbc;
?AES.
type(Cipher) when Cipher == null;
- Cipher == rc4_40;
- Cipher == rc4_56;
Cipher == rc4_128 ->
?STREAM;
type(Cipher) when Cipher == idea_cbc;
- Cipher == rc2_cbc_40;
- Cipher == rc2_cbc_56;
Cipher == des40_cbc;
Cipher == des_cbc;
Cipher == '3des_ede_cbc';
@@ -659,13 +458,8 @@ key_material(null) ->
key_material(Cipher) when Cipher == idea_cbc;
Cipher == rc4_128 ->
16;
-key_material(Cipher) when Cipher == rc2_cbc_56;
- Cipher == rc4_56 ->
- 7;
-key_material(Cipher) when Cipher == rc2_cbc_40;
- Cipher == rc4_40;
- Cipher == des40_cbc ->
- 5;
+%%key_material(des40_cbc) ->
+%% 5;
key_material(des_cbc) ->
8;
key_material('3des_ede_cbc') ->
@@ -678,10 +472,6 @@ key_material(aes_256_cbc) ->
expanded_key_material(null) ->
0;
expanded_key_material(Cipher) when Cipher == idea_cbc;
- Cipher == rc2_cbc_40;
- Cipher == rc2_cbc_56;
- Cipher == rc4_40;
- Cipher == rc4_56;
Cipher == rc4_128 ->
16;
expanded_key_material(Cipher) when Cipher == des_cbc;
@@ -696,13 +486,9 @@ expanded_key_material(Cipher) when Cipher == aes_128_cbc;
effective_key_bits(null) ->
0;
-effective_key_bits(Cipher) when Cipher == rc2_cbc_40;
- Cipher == rc4_40;
- Cipher == des40_cbc ->
- 40;
-effective_key_bits(Cipher) when Cipher == rc2_cbc_56;
- Cipher == rc4_56;
- Cipher == des_cbc ->
+%%effective_key_bits(des40_cbc) ->
+%% 40;
+effective_key_bits(des_cbc) ->
56;
effective_key_bits(Cipher) when Cipher == idea_cbc;
Cipher == rc4_128;
@@ -714,16 +500,12 @@ effective_key_bits(aes_256_cbc) ->
256.
iv_size(Cipher) when Cipher == null;
- Cipher == rc4_40;
- Cipher == rc4_56;
Cipher == rc4_128 ->
0;
iv_size(Cipher) ->
block_size(Cipher).
block_size(Cipher) when Cipher == idea_cbc;
- Cipher == rc2_cbc_40;
- Cipher == rc2_cbc_56;
Cipher == des40_cbc;
Cipher == des_cbc;
Cipher == '3des_ede_cbc' ->
@@ -763,9 +545,12 @@ generic_stream_cipher_from_bin(T, HashSz) ->
#generic_stream_cipher{content=Content,
mac=Mac}.
-check_padding(_GBC) ->
- ok.
+is_correct_padding(_, {3, 0}) ->
+ true;
+is_correct_padding(#generic_block_cipher{padding_length = Len, padding = Padding}, _) ->
+ list_to_binary(lists:duplicate(Len, Len)) == Padding.
+
get_padding(Length, BlockSize) ->
get_padding_aux(BlockSize, Length rem BlockSize).
diff --git a/lib/ssl/src/ssl_cipher.hrl b/lib/ssl/src/ssl_cipher.hrl
index 4304c501b7..80fe527f45 100644
--- a/lib/ssl/src/ssl_cipher.hrl
+++ b/lib/ssl/src/ssl_cipher.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,7 +57,7 @@
%% TLS_NULL_WITH_NULL_NULL = { 0x00,0x00 };
-define(TLS_NULL_WITH_NULL_NULL, <<?BYTE(16#00), ?BYTE(16#00)>>).
-%%% The following CipherSuite definitions require that the server
+%%% The following cipher suite definitions require that the server
%%% provide an RSA certificate that can be used for key exchange. The
%%% server may request either an RSA or a DSS signature-capable
%%% certificate in the certificate request message.
@@ -68,24 +68,15 @@
%% TLS_RSA_WITH_NULL_SHA = { 0x00,0x02 };
-define(TLS_RSA_WITH_NULL_SHA, <<?BYTE(16#00), ?BYTE(16#02)>>).
-%% TLS_RSA_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x03 };
--define(TLS_RSA_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#03)>>).
-
%% TLS_RSA_WITH_RC4_128_MD5 = { 0x00,0x04 };
-define(TLS_RSA_WITH_RC4_128_MD5, <<?BYTE(16#00), ?BYTE(16#04)>>).
%% TLS_RSA_WITH_RC4_128_SHA = { 0x00,0x05 };
-define(TLS_RSA_WITH_RC4_128_SHA, <<?BYTE(16#00), ?BYTE(16#05)>>).
-%% TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x06 };
--define(TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#06)>>).
-
%% TLS_RSA_WITH_IDEA_CBC_SHA = { 0x00,0x07 };
-define(TLS_RSA_WITH_IDEA_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#07)>>).
-%% TLS_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x08 };
--define(TLS_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#08)>>).
-
%% TLS_RSA_WITH_DES_CBC_SHA = { 0x00,0x09 };
-define(TLS_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#09)>>).
@@ -106,51 +97,33 @@
%%% provided by the client must use the parameters (group and
%%% generator) described by the server.
-%% TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0B };
--define(TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0B)>>).
-
%% TLS_DH_DSS_WITH_DES_CBC_SHA = { 0x00,0x0C };
-define(TLS_DH_DSS_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0C)>>).
%% TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0D };
-define(TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0D)>>).
-%% TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x0E };
--define(TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0E)>>).
-
%% TLS_DH_RSA_WITH_DES_CBC_SHA = { 0x00,0x0F };
-define(TLS_DH_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#0F)>>).
%% TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x10 };
-define(TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#10)>>).
-%% TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x11 };
--define(TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#11)>>).
-
%% TLS_DHE_DSS_WITH_DES_CBC_SHA = { 0x00,0x12 };
-define(TLS_DHE_DSS_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#12)>>).
%% TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x13 };
-define(TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#13)>>).
-%% TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x14 };
--define(TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#14)>>).
-
%% TLS_DHE_RSA_WITH_DES_CBC_SHA = { 0x00,0x15 };
-define(TLS_DHE_RSA_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#15)>>).
%% TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x16 };
-define(TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#16)>>).
-%% TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x17 };
--define(TLS_DH_anon_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#17)>>).
-
%% TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 };
-define(TLS_DH_anon_WITH_RC4_128_MD5, <<?BYTE(16#00),?BYTE(16#18)>>).
-%% TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA = { 0x00,0x19 };
--define(TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#19)>>).
-
%% TLS_DH_anon_WITH_DES_CBC_SHA = { 0x00,0x1A };
-define(TLS_DH_anon_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#1A)>>).
@@ -222,32 +195,9 @@
%% TLS_KRB5_WITH_IDEA_CBC_MD5 = { 0x00,0x25 };
-define(TLS_KRB5_WITH_IDEA_CBC_MD5, <<?BYTE(16#00), ?BYTE(16#25)>>).
-%% TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA = { 0x00,0x26 };
--define(TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, <<?BYTE(16#00), ?BYTE(16#26)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA = { 0x00,0x27 };
--define(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA, <<?BYTE(16#00), ?BYTE(16#27)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC4_40_SHA = { 0x00,0x28 };
--define(TLS_KRB5_EXPORT_WITH_RC4_40_SHA, <<?BYTE(16#00), ?BYTE(16#28)>>).
-
-%% TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 = { 0x00,0x29 };
--define(TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#29)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 = { 0x00,0x2A };
--define(TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5, <<?BYTE(16#00), ?BYTE(16#2A)>>).
-
-%% TLS_KRB5_EXPORT_WITH_RC4_40_MD5 = { 0x00,0x2B };
--define(TLS_KRB5_EXPORT_WITH_RC4_40_MD5, <<?BYTE(16#00), ?BYTE(16#2B)>>).
-
-%% Additional TLS ciphersuites from draft-ietf-tls-56-bit-ciphersuites-00.txt
-
--define(TLS_RSA_EXPORT1024_WITH_RC4_56_MD5, <<?BYTE(16#00), ?BYTE(16#60)>>).
--define(TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5, <<?BYTE(16#00), ?BYTE(16#61)>>).
--define(TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#62)>>).
--define(TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA, <<?BYTE(16#00), ?BYTE(16#63)>>).
--define(TLS_RSA_EXPORT1024_WITH_RC4_56_SHA, <<?BYTE(16#00), ?BYTE(16#64)>>).
--define(TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA, <<?BYTE(16#00), ?BYTE(16#65)>>).
--define(TLS_DHE_DSS_WITH_RC4_128_SHA, <<?BYTE(16#00), ?BYTE(16#66)>>).
+%% RFC 5746 - Not a real cipher suite used to signal empty "renegotiation_info" extension
+%% to avoid handshake failure from old servers that do not ignore
+%% hello extension data as they should.
+-define(TLS_EMPTY_RENEGOTIATION_INFO_SCSV, <<?BYTE(16#00), ?BYTE(16#FF)>>).
-endif. % -ifdef(ssl_cipher).
diff --git a/lib/ssl/src/ssl_connection.erl b/lib/ssl/src/ssl_connection.erl
index a406e86bbf..644c2772b2 100644
--- a/lib/ssl/src/ssl_connection.erl
+++ b/lib/ssl/src/ssl_connection.erl
@@ -39,7 +39,7 @@
-include_lib("public_key/include/public_key.hrl").
%% Internal application API
--export([send/2, send/3, recv/3, connect/7, ssl_accept/6, handshake/2,
+-export([send/2, recv/3, connect/7, ssl_accept/6, handshake/2,
socket_control/3, 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, renegotiation/1]).
@@ -58,6 +58,7 @@
transport_cb, % atom() - callback module
data_tag, % atom() - ex tcp.
close_tag, % atom() - ex tcp_closed
+ error_tag, % atom() - ex tcp_error
host, % string() | ipadress()
port, % integer()
socket, % socket()
@@ -86,7 +87,6 @@
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, % boolean()
renegotiation, % {boolean(), From | internal | peer}
recv_during_renegotiation, %boolean()
@@ -107,9 +107,9 @@
%% Description: Sends data over the ssl connection
%%--------------------------------------------------------------------
send(Pid, Data) ->
- sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, infinity).
-send(Pid, Data, Timeout) ->
- sync_send_all_state_event(Pid, {application_data, erlang:iolist_to_binary(Data)}, Timeout).
+ sync_send_all_state_event(Pid, {application_data,
+ erlang:iolist_to_binary(Data)}, infinity).
+
%%--------------------------------------------------------------------
%% Function: recv(Socket, Length Timeout) -> {ok, Data} | {error, reason}
%%
@@ -210,8 +210,6 @@ peername(ConnectionPid) ->
%%
%% Description: Same as inet:getopts/2
%%--------------------------------------------------------------------
-get_opts({ListenSocket, {_SslOpts, SockOpts}, _}, OptTags) ->
- get_socket_opts(ListenSocket, OptTags, SockOpts, []);
get_opts(ConnectionPid, OptTags) ->
sync_send_all_state_event(ConnectionPid, {get_opts, OptTags}).
%%--------------------------------------------------------------------
@@ -316,12 +314,14 @@ init([Role, Host, Port, Socket, {SSLOpts, _} = Options,
%%
%%--------------------------------------------------------------------
hello(start, #state{host = Host, port = Port, role = client,
- ssl_options = SslOpts,
- transport_cb = Transport, socket = Socket,
- connection_states = ConnectionStates}
+ ssl_options = SslOpts,
+ transport_cb = Transport, socket = Socket,
+ connection_states = ConnectionStates,
+ renegotiation = {Renegotiation, _}}
= State0) ->
Hello = ssl_handshake:client_hello(Host, Port,
- ConnectionStates, SslOpts),
+ ConnectionStates, SslOpts, Renegotiation),
+
Version = Hello#client_hello.client_version,
Hashes0 = ssl_handshake:init_hashes(),
{BinMsg, CS2, Hashes1} =
@@ -351,55 +351,60 @@ hello(#server_hello{cipher_suite = CipherSuite,
role = client,
negotiated_version = ReqVersion,
host = Host, port = Port,
+ renegotiation = {Renegotiation, _},
+ ssl_options = SslOptions,
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, KeyAlgorithm),
-
- State1 = State0#state{key_algorithm = KeyAlgorithm,
- negotiated_version = Version,
- connection_states = ConnectionStates1,
- premaster_secret = PremasterSecret},
-
- case ssl_session:is_new(OldId, NewId) of
- true ->
- Session = Session0#session{session_id = NewId,
- cipher_suite = CipherSuite,
+ case ssl_handshake:hello(Hello, SslOptions, ConnectionStates0, Renegotiation) of
+ {Version, NewId, ConnectionStates1} ->
+ {KeyAlgorithm, _, _} =
+ ssl_cipher:suite_definition(CipherSuite),
+
+ PremasterSecret = make_premaster_secret(ReqVersion, KeyAlgorithm),
+
+ State1 = State0#state{key_algorithm = KeyAlgorithm,
+ negotiated_version = Version,
+ connection_states = ConnectionStates1,
+ premaster_secret = PremasterSecret},
+
+ case ssl_session:is_new(OldId, NewId) of
+ true ->
+ Session = Session0#session{session_id = NewId,
+ cipher_suite = CipherSuite,
compression_method = Compression},
- {Record, State} = next_record(State1#state{session = Session}),
- next_state(certify, Record, State);
- false ->
- Session = CacheCb:lookup(Cache, {{Host, Port}, NewId}),
- case ssl_handshake:master_secret(Version, Session,
- ConnectionStates1, client) of
- {_, ConnectionStates2} ->
- {Record, State} =
- next_record(State1#state{
- connection_states = ConnectionStates2,
- session = Session}),
- next_state(abbreviated, Record, State);
- #alert{} = Alert ->
- handle_own_alert(Alert, Version, hello, State1),
- {stop, normal, State1}
- end
+ {Record, State} = next_record(State1#state{session = Session}),
+ next_state(certify, Record, State);
+ false ->
+ Session = CacheCb:lookup(Cache, {{Host, Port}, NewId}),
+ case ssl_handshake:master_secret(Version, Session,
+ ConnectionStates1, client) of
+ {_, ConnectionStates2} ->
+ {Record, State} =
+ next_record(State1#state{
+ connection_states = ConnectionStates2,
+ session = Session}),
+ next_state(abbreviated, Record, State);
+ #alert{} = Alert ->
+ handle_own_alert(Alert, Version, hello, State1),
+ {stop, normal, State1}
+ end
+ end;
+ #alert{} = Alert ->
+ handle_own_alert(Alert, ReqVersion, hello, State0),
+ {stop, normal, State0}
end;
hello(Hello = #client_hello{client_version = ClientVersion},
State = #state{connection_states = ConnectionStates0,
port = Port, session = Session0,
- session_cache = Cache,
+ renegotiation = {Renegotiation, _},
+ session_cache = Cache,
session_cache_cb = CacheCb,
ssl_options = SslOpts}) ->
- case ssl_handshake:hello(Hello, {Port, SslOpts,
- Session0, Cache, CacheCb,
- ConnectionStates0}) of
+ case ssl_handshake:hello(Hello, SslOpts, {Port, Session0, Cache, CacheCb,
+ ConnectionStates0}, Renegotiation) of
{Version, {Type, Session}, ConnectionStates} ->
do_server_hello(Type, State#state{connection_states =
ConnectionStates,
@@ -417,29 +422,35 @@ abbreviated(#hello_request{}, State0) ->
{Record, State} = next_record(State0),
next_state(hello, Record, State);
-abbreviated(Finished = #finished{},
+abbreviated(#finished{verify_data = Data} = Finished,
#state{role = server,
negotiated_version = Version,
tls_handshake_hashes = Hashes,
- session = #session{master_secret = MasterSecret}} =
+ session = #session{master_secret = MasterSecret},
+ connection_states = ConnectionStates0} =
State) ->
case ssl_handshake:verify_connection(Version, Finished, client,
MasterSecret, Hashes) of
verified ->
- next_state_connection(abbreviated, ack_connection(State));
+ ConnectionStates = ssl_record:set_client_verify_data(current_both, Data, ConnectionStates0),
+ next_state_connection(abbreviated,
+ ack_connection(State#state{connection_states = ConnectionStates}));
#alert{} = Alert ->
handle_own_alert(Alert, Version, abbreviated, State),
{stop, normal, State}
end;
-abbreviated(Finished = #finished{},
+abbreviated(#finished{verify_data = Data} = Finished,
#state{role = client, tls_handshake_hashes = Hashes0,
session = #session{master_secret = MasterSecret},
- negotiated_version = Version} = State) ->
+ negotiated_version = Version,
+ connection_states = ConnectionStates0} = State) ->
case ssl_handshake:verify_connection(Version, Finished, server,
MasterSecret, Hashes0) of
verified ->
- {ConnectionStates, Hashes} = finalize_client_handshake(State),
+ ConnectionStates1 = ssl_record:set_server_verify_data(current_read, Data, ConnectionStates0),
+ {ConnectionStates, Hashes} =
+ finalize_handshake(State#state{connection_states = ConnectionStates1}, abbreviated),
next_state_connection(abbreviated,
ack_connection(State#state{tls_handshake_hashes = Hashes,
connection_states =
@@ -493,7 +504,7 @@ certify(#certificate{} = Cert,
certify(#server_key_exchange{} = KeyExchangeMsg,
#state{role = client, negotiated_version = Version,
key_algorithm = Alg} = State0)
- when Alg == dhe_dss; Alg == dhe_rsa ->%%Not imp:Alg == dh_anon;Alg == krb5 ->
+ when Alg == dhe_dss; Alg == dhe_rsa ->
case handle_server_key(KeyExchangeMsg, State0) of
#state{} = State1 ->
{Record, State} = next_record(State1),
@@ -504,13 +515,9 @@ certify(#server_key_exchange{} = KeyExchangeMsg,
{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 ->
- Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE),
- handle_own_alert(Alert, Version, certify_server_key_exchange, State),
- {stop, normal, State};
+certify(#server_key_exchange{} = Msg,
+ #state{role = client, key_algorithm = rsa} = State) ->
+ handle_unexpected_message(Msg, certify_server_keyexchange, State);
certify(#certificate_request{}, State0) ->
{Record, State} = next_record(State0#state{client_certificate_requested = true}),
@@ -554,17 +561,12 @@ certify(#server_hello_done{},
{stop, normal, State0}
end;
-certify(#client_key_exchange{},
- State = #state{role = server,
- client_certificate_requested = true,
- ssl_options = #ssl_options{fail_if_no_peer_cert = true},
- negotiated_version = Version}) ->
+certify(#client_key_exchange{} = Msg,
+ #state{role = server,
+ client_certificate_requested = true,
+ ssl_options = #ssl_options{fail_if_no_peer_cert = true}} = State) ->
%% We expect a certificate here
- Alert = ?ALERT_REC(?FATAL, ?UNEXPECTED_MESSAGE),
- handle_own_alert(Alert, Version,
- certify_server_waiting_certificate, State),
- {stop, normal, State};
-
+ handle_unexpected_message(Msg, certify_client_key_exchange, State);
certify(#client_key_exchange{exchange_keys
= #encrypted_premaster_secret{premaster_secret
@@ -653,32 +655,37 @@ cipher(#certificate_verify{signature = Signature},
{stop, normal, State0}
end;
-cipher(#finished{} = Finished,
+cipher(#finished{verify_data = Data} = Finished,
#state{negotiated_version = Version,
host = Host,
port = Port,
role = Role,
session = #session{master_secret = MasterSecret}
= Session0,
- tls_handshake_hashes = Hashes} = State) ->
+ tls_handshake_hashes = Hashes0,
+ connection_states = ConnectionStates0} = State) ->
case ssl_handshake:verify_connection(Version, Finished,
opposite_role(Role),
- MasterSecret, Hashes) of
+ MasterSecret, Hashes0) of
verified ->
Session = register_session(Role, Host, Port, Session0),
case Role of
client ->
- next_state_connection(cipher, ack_connection(State#state{session = Session}));
+ ConnectionStates = ssl_record:set_server_verify_data(current_both, Data, ConnectionStates0),
+ next_state_connection(cipher, ack_connection(State#state{session = Session,
+ connection_states = ConnectionStates}));
server ->
- {NewConnectionStates, NewHashes} =
- finalize_server_handshake(State#state{
- session = Session}),
+ ConnectionStates1 = ssl_record:set_client_verify_data(current_read, Data, ConnectionStates0),
+ {ConnectionStates, Hashes} =
+ finalize_handshake(State#state{
+ connection_states = ConnectionStates1,
+ session = Session}, cipher),
next_state_connection(cipher, ack_connection(State#state{connection_states =
- NewConnectionStates,
+ ConnectionStates,
session = Session,
tls_handshake_hashes =
- NewHashes}))
+ Hashes}))
end;
#alert{} = Alert ->
handle_own_alert(Alert, Version, cipher, State),
@@ -695,10 +702,12 @@ connection(#hello_request{}, #state{host = Host, port = Port,
negotiated_version = Version,
transport_cb = Transport,
connection_states = ConnectionStates0,
+ renegotiation = {Renegotiation, _},
tls_handshake_hashes = Hashes0} = State0) ->
-
+
Hello = ssl_handshake:client_hello(Host, Port,
- ConnectionStates0, SslOpts),
+ ConnectionStates0, SslOpts, Renegotiation),
+
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(Hello, Version, ConnectionStates0, Hashes0),
Transport:send(Socket, BinMsg),
@@ -797,10 +806,22 @@ handle_sync_event(start, From, StateName, State) ->
handle_sync_event(close, _, _StateName, State) ->
{stop, normal, ok, State};
-handle_sync_event({shutdown, How}, _, StateName,
- #state{transport_cb = CbModule,
+handle_sync_event({shutdown, How0}, _, StateName,
+ #state{transport_cb = Transport,
+ negotiated_version = Version,
+ connection_states = ConnectionStates,
socket = Socket} = State) ->
- case CbModule:shutdown(Socket, How) of
+ case How0 of
+ How when How == write; How == both ->
+ Alert = ?ALERT_REC(?WARNING, ?CLOSE_NOTIFY),
+ {BinMsg, _} =
+ encode_alert(Alert, Version, ConnectionStates),
+ Transport:send(Socket, BinMsg);
+ _ ->
+ ok
+ end,
+
+ case Transport:shutdown(Socket, How0) of
ok ->
{reply, ok, StateName, State};
Error ->
@@ -913,14 +934,9 @@ handle_sync_event(peer_certificate, _, StateName,
%% raw data from TCP, unpack records
handle_info({Protocol, _, Data}, StateName,
#state{data_tag = Protocol,
- negotiated_version = Version,
- tls_record_buffer = Buf0,
- tls_cipher_texts = CT0} = State0) ->
- case ssl_record:get_tls_records(Data, Buf0) of
- {Records, Buf1} ->
- CT1 = CT0 ++ Records,
- {Record, State} = next_record(State0#state{tls_record_buffer = Buf1,
- tls_cipher_texts = CT1}),
+ negotiated_version = Version} = State0) ->
+ case next_tls_record(Data, State0) of
+ {Record, State} ->
next_state(StateName, Record, State);
#alert{} = Alert ->
handle_own_alert(Alert, Version, StateName, State0),
@@ -944,14 +960,29 @@ handle_info({CloseTag, Socket}, _StateName,
alert_user(Opts#socket_options.active, Pid, From,
?ALERT_REC(?WARNING, ?CLOSE_NOTIFY), Role),
{stop, normal, State};
-
+
+handle_info({ErrorTag, Socket, econnaborted}, StateName,
+ #state{socket = Socket, from = User, role = Role,
+ error_tag = ErrorTag} = State) when StateName =/= connection ->
+ alert_user(User, ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE), Role),
+ {stop, normal, State};
+
+handle_info({ErrorTag, Socket, Reason}, _,
+ #state{socket = Socket, from = User,
+ role = Role, error_tag = ErrorTag} = State) ->
+ Report = io_lib:format("SSL: Socket error: ~p ~n", [Reason]),
+ error_logger:info_report(Report),
+ alert_user(User, ?ALERT_REC(?FATAL, ?CLOSE_NOTIFY), Role),
+ {stop, normal, State};
+
handle_info({'DOWN', MonitorRef, _, _, _}, _,
State = #state{user_application={MonitorRef,_Pid}}) ->
{stop, normal, State};
-handle_info(A, StateName, State) ->
- io:format("SSL: Bad info (state ~w): ~w\n", [StateName, A]),
- {stop, bad_info, State}.
+handle_info(Msg, StateName, State) ->
+ Report = io_lib:format("SSL: Got unexpected info: ~p ~n", [Msg]),
+ error_logger:info_report(Report),
+ {next_state, StateName, State}.
%%--------------------------------------------------------------------
%% Function: terminate(Reason, StateName, State) -> void()
@@ -970,14 +1001,14 @@ terminate(_Reason, connection, #state{negotiated_version = Version,
{BinAlert, _} = encode_alert(?ALERT_REC(?WARNING,?CLOSE_NOTIFY),
Version, ConnectionStates),
Transport:send(Socket, BinAlert),
- Transport:shutdown(Socket, read_write),
+ workaround_transport_delivery_problems(Socket, Transport),
Transport:close(Socket);
terminate(_Reason, _StateName, #state{transport_cb = Transport,
socket = Socket, send_queue = SendQueue,
renegotiation = Renegotiate}) ->
notify_senders(SendQueue),
notify_renegotiater(Renegotiate),
- Transport:shutdown(Socket, read_write),
+ workaround_transport_delivery_problems(Socket, Transport),
Transport:close(Socket).
%%--------------------------------------------------------------------
@@ -991,7 +1022,7 @@ code_change(_OldVsn, StateName, State, _Extra) ->
%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
-start_fsm(Role, Host, Port, Socket, Opts, User, {CbModule, _,_} = CbInfo,
+start_fsm(Role, Host, Port, Socket, Opts, User, {CbModule, _,_, _} = CbInfo,
Timeout) ->
case ssl_connection_sup:start_child([Role, Host, Port, Socket,
Opts, User, CbInfo]) of
@@ -1025,16 +1056,9 @@ 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 Initializing: ~p ~n",
- [_Error, CACertFile]),
- error_logger:error_report(Report),
- throw(ecacertfile)
+ {error, Reason} ->
+ handle_file_error(?LINE, error, Reason, CACertFile, ecacertfile,
+ erlang:get_stacktrace())
end.
init_certificates(CertDbRef, CacheRef, CertFile, client) ->
@@ -1050,63 +1074,60 @@ init_certificates(CertDbRef, CacheRef, CertFile, server) ->
[OwnCert] = ssl_certificate:file_to_certificats(CertFile),
{ok, CertDbRef, CacheRef, OwnCert}
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)
+ Error:Reason ->
+ handle_file_error(?LINE, Error, Reason, CertFile, ecertfile,
+ erlang:get_stacktrace())
end.
init_private_key(undefined, "", _Password, client) ->
undefined;
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],
- {ok, Decoded} = public_key:decode_private_key(Der,Password),
- Decoded
- 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)
+ case ssl_manager:cache_pem_file(KeyFile) of
+ {ok, List} ->
+ [Der] = [Der || Der = {PKey, _ , _} <- List,
+ PKey =:= rsa_private_key orelse
+ PKey =:= dsa_private_key],
+ {ok, Decoded} = public_key:decode_private_key(Der,Password),
+ Decoded;
+ {error, Reason} ->
+ handle_file_error(?LINE, error, Reason, KeyFile, ekeyfile,
+ erlang:get_stacktrace())
end;
+
init_private_key(PrivateKey, _, _,_) ->
PrivateKey.
+handle_file_error(Line, Error, {badmatch, Reason}, File, Throw, Stack) ->
+ file_error(Line, Error, Reason, File, Throw, Stack);
+handle_file_error(Line, Error, Reason, File, Throw, Stack) ->
+ file_error(Line, Error, Reason, File, Throw, Stack).
+
+file_error(Line, Error, Reason, File, Throw, Stack) ->
+ Report = io_lib:format("SSL: ~p: ~p:~p ~s~n ~p~n",
+ [Line, Error, Reason, File, Stack]),
+ error_logger:error_report(Report),
+ throw(Throw).
+
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
+ case ssl_manager:cache_pem_file(DHParamFile) of
+ {ok, List} ->
+ case [Der || Der = {dh_params, _ , _} <- List] of
+ [Der] ->
+ {ok, Decoded} = public_key:decode_dhparams(Der),
+ Decoded;
+ [] ->
+ ?DEFAULT_DIFFIE_HELLMAN_PARAMS
+ end;
+ {error, Reason} ->
+ handle_file_error(?LINE, error, Reason, DHParamFile, edhfile, erlang:get_stacktrace())
end.
sync_send_all_state_event(FsmPid, Event) ->
- sync_send_all_state_event(FsmPid, Event, ?DEFAULT_TIMEOUT).
+ sync_send_all_state_event(FsmPid, Event, infinity).
sync_send_all_state_event(FsmPid, Event, Timeout) ->
try gen_fsm:sync_send_all_state_event(FsmPid, Event, Timeout)
@@ -1116,6 +1137,8 @@ sync_send_all_state_event(FsmPid, Event, Timeout) ->
exit:{timeout, _} ->
{error, timeout};
exit:{normal, _} ->
+ {error, closed};
+ exit:{shutdown, _} ->
{error, closed}
end.
@@ -1160,47 +1183,52 @@ verify_client_cert(#state{client_certificate_requested = true, role = client,
case ssl_handshake:client_certificate_verify(OwnCert, MasterSecret,
Version, KeyAlg,
PrivateKey, Hashes0) of
- ignore -> %% No key or cert or fixed_diffie_hellman
- State;
- Verified ->
+ #certificate_verify{} = Verified ->
{BinVerified, ConnectionStates1, Hashes1} =
encode_handshake(Verified, KeyAlg, Version,
ConnectionStates0, Hashes0),
Transport:send(Socket, BinVerified),
State#state{connection_states = ConnectionStates1,
- tls_handshake_hashes = Hashes1}
+ tls_handshake_hashes = Hashes1};
+ ignore ->
+ State;
+ #alert{} = Alert ->
+ handle_own_alert(Alert, Version, certify, State)
+
end;
verify_client_cert(#state{client_certificate_requested = false} = State) ->
State.
do_server_hello(Type, #state{negotiated_version = Version,
session = Session,
- connection_states = ConnectionStates0}
+ connection_states = ConnectionStates0,
+ renegotiation = {Renegotiation, _}}
= State0) when is_atom(Type) ->
ServerHello =
ssl_handshake:server_hello(Session#session.session_id, Version,
- ConnectionStates0),
- State = server_hello(ServerHello, State0),
+ ConnectionStates0, Renegotiation),
+ State1 = server_hello(ServerHello, State0),
case Type of
new ->
- do_server_hello(ServerHello, State);
+ do_server_hello(ServerHello, State1);
resumed ->
+ ConnectionStates1 = State1#state.connection_states,
case ssl_handshake:master_secret(Version, Session,
- ConnectionStates0, server) of
- {_, ConnectionStates1} ->
- State1 = State#state{connection_states=ConnectionStates1,
- session = Session},
+ ConnectionStates1, server) of
+ {_, ConnectionStates2} ->
+ State2 = State1#state{connection_states=ConnectionStates2,
+ session = Session},
{ConnectionStates, Hashes} =
- finalize_server_handshake(State1),
- Resumed0 = State1#state{connection_states =
- ConnectionStates,
- tls_handshake_hashes = Hashes},
- {Record, Resumed} = next_record(Resumed0),
- next_state(abbreviated, Record, Resumed);
+ finalize_handshake(State2, abbreviated),
+ State3 = State2#state{connection_states =
+ ConnectionStates,
+ tls_handshake_hashes = Hashes},
+ {Record, State} = next_record(State3),
+ next_state(abbreviated, Record, State);
#alert{} = Alert ->
- handle_own_alert(Alert, Version, hello, State),
- {stop, normal, State}
+ handle_own_alert(Alert, Version, hello, State1),
+ {stop, normal, State1}
end
end;
@@ -1228,7 +1256,7 @@ client_certify_and_key_exchange(#state{negotiated_version = Version} =
State0) ->
try do_client_certify_and_key_exchange(State0) of
State1 = #state{} ->
- {ConnectionStates, Hashes} = finalize_client_handshake(State1),
+ {ConnectionStates, Hashes} = finalize_handshake(State1, certify),
State2 = State1#state{connection_states = ConnectionStates,
%% Reinitialize
client_certificate_requested = false,
@@ -1257,8 +1285,7 @@ server_hello(ServerHello, #state{transport_cb = Transport,
connection_states = ConnectionStates0,
tls_handshake_hashes = Hashes0} = State) ->
CipherSuite = ServerHello#server_hello.cipher_suite,
- {KeyAlgorithm, _, _, _} = ssl_cipher:suite_definition(CipherSuite),
- %% Version = ServerHello#server_hello.server_version, TODO ska kontrolleras
+ {KeyAlgorithm, _, _} = ssl_cipher:suite_definition(CipherSuite),
{BinMsg, ConnectionStates1, Hashes1} =
encode_handshake(ServerHello, Version, ConnectionStates0, Hashes0),
Transport:send(Socket, BinMsg),
@@ -1300,18 +1327,8 @@ certify_server(#state{transport_cb = Transport,
throw(Alert)
end.
-key_exchange(#state{role = server, key_algorithm = Algo} = State)
- when Algo == rsa;
- Algo == dh_dss;
- Algo == dh_rsa ->
+key_exchange(#state{role = server, key_algorithm = rsa} = State) ->
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;
-
key_exchange(#state{role = server, key_algorithm = Algo,
diffie_hellman_params = Params,
private_key = PrivateKey,
@@ -1362,7 +1379,6 @@ key_exchange(#state{role = client,
Transport:send(Socket, BinMsg),
State#state{connection_states = ConnectionStates1,
tls_handshake_hashes = Hashes1};
-
key_exchange(#state{role = client,
connection_states = ConnectionStates0,
key_algorithm = Algorithm,
@@ -1379,24 +1395,6 @@ key_exchange(#state{role = client,
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),
- State#state{connection_states = ConnectionStates1,
tls_handshake_hashes = Hashes1}.
rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
@@ -1410,17 +1408,6 @@ rsa_key_exchange(PremasterSecret, PublicKeyInfo = {Algorithm, _, _})
rsa_key_exchange(_, _) ->
throw (?ALERT_REC(?FATAL,?HANDSHAKE_FAILURE)).
-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 ->
- {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,
cert_db_ref = CertDbRef,
@@ -1439,45 +1426,44 @@ request_client_cert(#state{ssl_options = #ssl_options{verify = verify_none}} =
State) ->
State.
-finalize_client_handshake(#state{connection_states = ConnectionStates0}
- = State) ->
- ConnectionStates1 =
- cipher_protocol(State#state{connection_states =
- ConnectionStates0}),
- ConnectionStates2 =
- ssl_record:activate_pending_connection_state(ConnectionStates1,
+finalize_handshake(State, StateName) ->
+ ConnectionStates0 = cipher_protocol(State),
+ ConnectionStates =
+ ssl_record:activate_pending_connection_state(ConnectionStates0,
write),
- finished(State#state{connection_states = ConnectionStates2}).
+ finished(State#state{connection_states = ConnectionStates}, StateName).
-
-finalize_server_handshake(State) ->
- ConnectionStates0 = cipher_protocol(State),
- ConnectionStates =
- ssl_record:activate_pending_connection_state(ConnectionStates0,
- write),
- finished(State#state{connection_states = ConnectionStates}).
-
-cipher_protocol(#state{connection_states = ConnectionStates,
+cipher_protocol(#state{connection_states = ConnectionStates0,
socket = Socket,
negotiated_version = Version,
transport_cb = Transport}) ->
- {BinChangeCipher, NewConnectionStates} =
+ {BinChangeCipher, ConnectionStates} =
encode_change_cipher(#change_cipher_spec{},
- Version, ConnectionStates),
+ Version, ConnectionStates0),
Transport:send(Socket, BinChangeCipher),
- NewConnectionStates.
+ ConnectionStates.
finished(#state{role = Role, socket = Socket, negotiated_version = Version,
transport_cb = Transport,
session = Session,
- connection_states = ConnectionStates,
- tls_handshake_hashes = Hashes}) ->
+ connection_states = ConnectionStates0,
+ tls_handshake_hashes = Hashes0}, StateName) ->
MasterSecret = Session#session.master_secret,
- Finished = ssl_handshake:finished(Version, Role, MasterSecret, Hashes),
- {BinFinished, NewConnectionStates, NewHashes} =
- encode_handshake(Finished, Version, ConnectionStates, Hashes),
+ Finished = ssl_handshake:finished(Version, Role, MasterSecret, Hashes0),
+ ConnectionStates1 = save_verify_data(Role, Finished, ConnectionStates0, StateName),
+ {BinFinished, ConnectionStates, Hashes} =
+ encode_handshake(Finished, Version, ConnectionStates1, Hashes0),
Transport:send(Socket, BinFinished),
- {NewConnectionStates, NewHashes}.
+ {ConnectionStates, Hashes}.
+
+save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, certify) ->
+ ssl_record:set_client_verify_data(current_write, Data, ConnectionStates);
+save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, cipher) ->
+ ssl_record:set_server_verify_data(current_both, Data, ConnectionStates);
+save_verify_data(client, #finished{verify_data = Data}, ConnectionStates, abbreviated) ->
+ ssl_record:set_client_verify_data(current_both, Data, ConnectionStates);
+save_verify_data(server, #finished{verify_data = Data}, ConnectionStates, abbreviated) ->
+ ssl_record:set_server_verify_data(current_write, Data, ConnectionStates).
handle_server_key(
#server_key_exchange{params =
@@ -1710,20 +1696,13 @@ format_packet_error(#socket_options{active = false, mode = Mode}, Data) ->
format_packet_error(#socket_options{active = _, mode = Mode}, Data) ->
{ssl_error, sslsocket(), {invalid_packet, format_reply(Mode, raw, 0, Data)}}.
-format_reply(_, http, _,Data) -> Data;
-format_reply(_, http_bin, _, Data) -> Data;
-format_reply(_, {http, headers}, _,Data) -> Data;
-format_reply(_, {http_bin, headers}, _, Data) -> Data;
-format_reply(_, asn1, _,Data) -> Data;
-format_reply(_, cdr, _, Data) -> Data;
-format_reply(_, sunrm, _,Data) -> Data;
-format_reply(_, fcgi, _, Data) -> Data;
-format_reply(_, tpkt, _, Data) -> Data;
-format_reply(_, line, _, Data) -> Data;
format_reply(binary, _, N, Data) when N > 0 -> % Header mode
header(N, Data);
format_reply(binary, _, _, Data) -> Data;
-format_reply(list, _, _, Data) -> binary_to_list(Data).
+format_reply(list, Packet, _, Data) when is_integer(Packet); Packet == raw ->
+ binary_to_list(Data);
+format_reply(list, _,_, Data) ->
+ Data.
header(0, <<>>) ->
<<>>;
@@ -1735,13 +1714,7 @@ header(N, Binary) ->
<<?BYTE(ByteN), NewBinary/binary>> = Binary,
[ByteN | header(N-1, NewBinary)].
-%% tcp_closed
-send_or_reply(false, _Pid, undefined, _Data) ->
- Report = io_lib:format("SSL(debug): Unexpected Data ~p ~n",[_Data]),
- error_logger:error_report(Report),
- erlang:error({badarg, _Pid, undefined, _Data}),
- ok;
-send_or_reply(false, _Pid, From, Data) ->
+send_or_reply(false, _Pid, From, Data) when From =/= undefined ->
gen_fsm:reply(From, Data);
send_or_reply(_, Pid, _From, Data) ->
send_user(Pid, Data).
@@ -1754,6 +1727,9 @@ opposite_role(server) ->
send_user(Pid, Msg) ->
Pid ! Msg.
+next_state(_, #alert{} = Alert, #state{negotiated_version = Version} = State) ->
+ handle_own_alert(Alert, Version, decipher_error, State),
+ {stop, normal, State};
next_state(Next, no_record, State) ->
{next_state, Next, State};
@@ -1781,7 +1757,7 @@ next_state(StateName, #ssl_tls{type = ?HANDSHAKE, fragment = Data},
Hs1 = ssl_handshake:update_hashes(Hs0, Raw),
?MODULE:SName(Packet, State#state{tls_handshake_hashes=Hs1,
renegotiation = {true, peer}});
- ({Packet, Raw}, {next_state, SName, State = #state{tls_handshake_hashes=Hs0}}) ->
+ ({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
@@ -1802,7 +1778,6 @@ next_state(StateName, #ssl_tls{type = ?APPLICATION_DATA, fragment = Data}, State
{Record, State} ->
next_state(StateName, Record, State)
end;
-
next_state(StateName, #ssl_tls{type = ?CHANGE_CIPHER_SPEC, fragment = <<1>>} =
_ChangeCipher,
#state{connection_states = ConnectionStates0} = State0) ->
@@ -1816,13 +1791,28 @@ next_state(StateName, #ssl_tls{type = _Unknown}, State0) ->
{Record, State} = next_record(State0),
next_state(StateName, Record, State).
+next_tls_record(Data, #state{tls_record_buffer = Buf0,
+ tls_cipher_texts = CT0} = State0) ->
+ case ssl_record:get_tls_records(Data, Buf0) of
+ {Records, Buf1} ->
+ CT1 = CT0 ++ Records,
+ next_record(State0#state{tls_record_buffer = Buf1,
+ tls_cipher_texts = CT1});
+ #alert{} = Alert ->
+ Alert
+ end.
+
next_record(#state{tls_cipher_texts = [], socket = Socket} = State) ->
inet:setopts(Socket, [{active,once}]),
{no_record, State};
next_record(#state{tls_cipher_texts = [CT | Rest],
connection_states = ConnStates0} = State) ->
- {Plain, ConnStates} = ssl_record:decode_cipher_text(CT, ConnStates0),
- {Plain, State#state{tls_cipher_texts = Rest, connection_states = ConnStates}}.
+ case ssl_record:decode_cipher_text(CT, ConnStates0) of
+ {Plain, ConnStates} ->
+ {Plain, State#state{tls_cipher_texts = Rest, connection_states = ConnStates}};
+ #alert{} = Alert ->
+ {Alert, State}
+ end.
next_record_if_active(State =
#state{socket_options =
@@ -1892,7 +1882,7 @@ invalidate_session(server, _, Port, Session) ->
ssl_manager:invalidate_session(Port, Session).
initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User,
- {CbModule, DataTag, CloseTag}) ->
+ {CbModule, DataTag, CloseTag, ErrorTag}) ->
ConnectionStates = ssl_record:init_connection_states(Role),
SessionCacheCb = case application:get_env(ssl, session_cb) of
@@ -1912,6 +1902,7 @@ initial_state(Role, Host, Port, Socket, {SSLOptions, SocketOptions}, User,
transport_cb = CbModule,
data_tag = DataTag,
close_tag = CloseTag,
+ error_tag = ErrorTag,
role = Role,
host = Host,
port = Port,
@@ -1991,34 +1982,19 @@ handle_alerts(_, {stop, _, _} = Stop) ->
handle_alerts([Alert | Alerts], {next_state, StateName, State}) ->
handle_alerts(Alerts, handle_alert(Alert, StateName, State)).
-handle_alert(#alert{level = ?FATAL} = Alert, connection,
- #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),
- log_alert(Log, connection, Alert),
- alert_user(Opts#socket_options.active, Pid, From, Alert, Role),
- {stop, normal, State};
-
-handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert,
- connection, #state{from = From,
- role = Role,
- user_application = {_Mon, Pid},
- socket_options = Opts} = State) ->
- alert_user(Opts#socket_options.active, Pid, From, Alert, Role),
- {stop, normal, State};
-
handle_alert(#alert{level = ?FATAL} = Alert, StateName,
#state{from = From, host = Host, port = Port, session = Session,
- log_alert = Log, role = Role} = State) ->
+ user_application = {_Mon, Pid},
+ log_alert = Log, role = Role, socket_options = Opts} = State) ->
invalidate_session(Role, Host, Port, Session),
log_alert(Log, StateName, Alert),
- alert_user(From, Alert, Role),
+ alert_user(StateName, Opts, Pid, From, Alert, Role),
{stop, normal, State};
+
handle_alert(#alert{level = ?WARNING, description = ?CLOSE_NOTIFY} = Alert,
- _, #state{from = From, role = Role} = State) ->
- alert_user(From, Alert, Role),
+ StateName, #state{from = From, role = Role,
+ user_application = {_Mon, Pid}, socket_options = Opts} = State) ->
+ alert_user(StateName, Opts, Pid, From, Alert, Role),
{stop, normal, State};
handle_alert(#alert{level = ?WARNING, description = ?NO_RENEGOTIATION} = Alert, StateName,
@@ -2041,6 +2017,11 @@ handle_alert(#alert{level = ?WARNING, description = ?USER_CANCELED} = Alert, Sta
{Record, State} = next_record(State0),
next_state(StateName, Record, State).
+alert_user(connection, Opts, Pid, From, Alert, Role) ->
+ alert_user(Opts#socket_options.active, Pid, From, Alert, Role);
+alert_user(_, _, _, From, Alert, Role) ->
+ alert_user(From, Alert, Role).
+
alert_user(From, Alert, Role) ->
alert_user(false, no_pid, From, Alert, Role).
@@ -2060,13 +2041,13 @@ alert_user(Active, Pid, From, Alert, Role) ->
{ssl_error, sslsocket(), ReasonCode})
end.
-log_alert(true, StateName, Alert) ->
+log_alert(true, Info, Alert) ->
Txt = ssl_alert:alert_txt(Alert),
- error_logger:format("SSL: ~p: ~s\n", [StateName, Txt]);
+ error_logger:format("SSL: ~p: ~s\n", [Info, Txt]);
log_alert(false, _, _) ->
ok.
-handle_own_alert(Alert, Version, StateName,
+handle_own_alert(Alert, Version, Info,
#state{transport_cb = Transport,
socket = Socket,
from = User,
@@ -2076,31 +2057,24 @@ handle_own_alert(Alert, Version, StateName,
try %% Try to tell the other side
{BinMsg, _} =
encode_alert(Alert, Version, ConnectionStates),
- %% Try to make sure alert will be sent before socket is closed
- %% when process ends. This will help on some
- %% linux platforms and knowingly not break anything on other
- %% platforms. Other platforms will benefit from shutdown that is now
- %% done before close.
- inet:setopts(Socket, [{nodelay, true}]),
+ linux_workaround_transport_delivery_problems(Alert, Socket),
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),
+ log_alert(Log, Info, Alert),
alert_user(User, Alert, Role)
catch _:_ ->
ok
end.
-handle_unexpected_message(_Msg, StateName, #state{negotiated_version = Version} = State) ->
+handle_unexpected_message(Msg, Info, #state{negotiated_version = Version} = State) ->
Alert = ?ALERT_REC(?FATAL,?UNEXPECTED_MESSAGE),
- handle_own_alert(Alert, Version, StateName, State),
+ handle_own_alert(Alert, Version, {Info, Msg}, State),
{stop, normal, State}.
-make_premaster_secret({MajVer, MinVer}, Alg) when Alg == rsa;
- Alg == dh_dss;
- Alg == dh_rsa ->
+make_premaster_secret({MajVer, MinVer}, rsa) ->
Rand = crypto:rand_bytes(?NUM_OF_PREMASTERSECRET_BYTES-2),
<<?BYTE(MajVer), ?BYTE(MinVer), Rand/binary>>;
make_premaster_secret(_, _) ->
@@ -2155,3 +2129,21 @@ notify_renegotiater({true, From}) when not is_atom(From) ->
gen_fsm:reply(From, {error, closed});
notify_renegotiater(_) ->
ok.
+
+workaround_transport_delivery_problems(Socket, Transport) ->
+ %% Standard trick to try to make sure all
+ %% data sent to to tcp port is really sent
+ %% before tcp port is closed.
+ inet:setopts(Socket, [{active, false}]),
+ Transport:shutdown(Socket, write),
+ Transport:recv(Socket, 0).
+
+linux_workaround_transport_delivery_problems(#alert{level = ?FATAL}, Socket) ->
+ case os:type() of
+ {unix, linux} ->
+ inet:setopts(Socket, [{nodelay, true}]);
+ _ ->
+ ok
+ end;
+linux_workaround_transport_delivery_problems(_, _) ->
+ ok.
diff --git a/lib/ssl/src/ssl_handshake.erl b/lib/ssl/src/ssl_handshake.erl
index 9f5ac7106a..454d726f0d 100644
--- a/lib/ssl/src/ssl_handshake.erl
+++ b/lib/ssl/src/ssl_handshake.erl
@@ -31,7 +31,7 @@
-include("ssl_debug.hrl").
-include_lib("public_key/include/public_key.hrl").
--export([master_secret/4, client_hello/4, server_hello/3, hello/2,
+-export([master_secret/4, client_hello/5, server_hello/4, hello/4,
hello_request/0, certify/7, certificate/3,
client_certificate_verify/6,
certificate_verify/6, certificate_request/2,
@@ -57,7 +57,7 @@
%%--------------------------------------------------------------------
client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions,
ciphers = Ciphers}
- = SslOpts) ->
+ = SslOpts, Renegotiation) ->
Fun = fun(Version) ->
ssl_record:protocol_version(Version)
@@ -70,22 +70,25 @@ client_hello(Host, Port, ConnectionStates, #ssl_options{versions = Versions,
#client_hello{session_id = Id,
client_version = Version,
- cipher_suites = Ciphers,
+ cipher_suites = cipher_suites(Ciphers, Renegotiation),
compression_methods = ssl_record:compressions(),
- random = SecParams#security_parameters.client_random
+ random = SecParams#security_parameters.client_random,
+ renegotiation_info =
+ renegotiation_info(client, ConnectionStates, Renegotiation)
}.
%%--------------------------------------------------------------------
-%% Function: server_hello(Host, Port, SessionId,
-%% Version, ConnectionStates) -> #server_hello{}
+%% Function: server_hello(SessionId, Version,
+%% ConnectionStates, Renegotiation) -> #server_hello{}
%% SessionId
%% Version
-%% ConnectionStates
+%% ConnectionStates
+%% Renegotiation
%%
%%
%% Description: Creates a server hello message.
%%--------------------------------------------------------------------
-server_hello(SessionId, Version, ConnectionStates) ->
+server_hello(SessionId, Version, ConnectionStates, Renegotiation) ->
Pending = ssl_record:pending_connection_state(ConnectionStates, read),
SecParams = Pending#connection_state.security_parameters,
#server_hello{server_version = Version,
@@ -93,7 +96,9 @@ server_hello(SessionId, Version, ConnectionStates) ->
compression_method =
SecParams#security_parameters.compression_algorithm,
random = SecParams#security_parameters.server_random,
- session_id = SessionId
+ session_id = SessionId,
+ renegotiation_info =
+ renegotiation_info(server, ConnectionStates, Renegotiation)
}.
%%--------------------------------------------------------------------
@@ -106,27 +111,46 @@ hello_request() ->
#hello_request{}.
%%--------------------------------------------------------------------
-%% Function: hello(Hello, Info) ->
+%% Function: hello(Hello, Info, Renegotiation) ->
%% {Version, Id, NewConnectionStates} |
%% #alert{}
%%
%% Hello = #client_hello{} | #server_hello{}
-%% Info = ConnectionStates | {Port, Session, ConnectionStates}
+%% Info = ConnectionStates | {Port, #ssl_options{}, Session,
+%% Cahce, CahceCb, ConnectionStates}
%% ConnectionStates = #connection_states{}
+%% Renegotiation = boolean()
%%
%% Description: Handles a recieved hello message
%%--------------------------------------------------------------------
hello(#server_hello{cipher_suite = CipherSuite, server_version = Version,
compression_method = Compression, random = Random,
- session_id = SessionId}, ConnectionStates) ->
- NewConnectionStates =
- hello_pending_connection_states(client, CipherSuite, Random,
- Compression, ConnectionStates),
- {Version, SessionId, NewConnectionStates};
-
-hello(#client_hello{client_version = ClientVersion, random = Random} = Hello,
- {Port, #ssl_options{versions = Versions} = SslOpts,
- Session0, Cache, CacheCb, ConnectionStates0}) ->
+ session_id = SessionId, renegotiation_info = Info},
+ #ssl_options{secure_renegotiate = SecureRenegotation},
+ ConnectionStates0, Renegotiation) ->
+
+ case ssl_record:is_acceptable_version(Version) of
+ true ->
+ case handle_renegotiation_info(client, Info, ConnectionStates0,
+ Renegotiation, SecureRenegotation, []) of
+ {ok, ConnectionStates1} ->
+ ConnectionStates =
+ hello_pending_connection_states(client, CipherSuite, Random,
+ Compression, ConnectionStates1),
+ {Version, SessionId, ConnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end;
+ false ->
+ ?ALERT_REC(?FATAL, ?PROTOCOL_VERSION)
+ end;
+
+hello(#client_hello{client_version = ClientVersion, random = Random,
+ cipher_suites = CipherSuites,
+ renegotiation_info = Info} = Hello,
+ #ssl_options{versions = Versions,
+ secure_renegotiate = SecureRenegotation} = SslOpts,
+ {Port, Session0, Cache, CacheCb, ConnectionStates0}, Renegotiation) ->
Version = select_version(ClientVersion, Versions),
case ssl_record:is_acceptable_version(Version) of
true ->
@@ -138,13 +162,20 @@ hello(#client_hello{client_version = ClientVersion, random = Random} = Hello,
no_suite ->
?ALERT_REC(?FATAL, ?INSUFFICIENT_SECURITY);
_ ->
- ConnectionStates =
- hello_pending_connection_states(server,
- CipherSuite,
- Random,
- Compression,
- ConnectionStates0),
- {Version, {Type, Session}, ConnectionStates}
+ case handle_renegotiation_info(server, Info, ConnectionStates0,
+ Renegotiation, SecureRenegotation,
+ CipherSuites) of
+ {ok, ConnectionStates1} ->
+ ConnectionStates =
+ hello_pending_connection_states(server,
+ CipherSuite,
+ Random,
+ Compression,
+ ConnectionStates1),
+ {Version, {Type, Session}, ConnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end
end;
false ->
?ALERT_REC(?FATAL, ?PROTOCOL_VERSION)
@@ -256,7 +287,7 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm,
PrivateKey, {Hashes0, _}) ->
case public_key:pkix_is_fixed_dh_cert(OwnCert) of
true ->
- ignore;
+ ?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE);
false ->
Hashes =
calc_certificate_verify(Version, MasterSecret,
@@ -276,7 +307,6 @@ client_certificate_verify(OwnCert, MasterSecret, Version, Algorithm,
certificate_verify(Signature, {_, PublicKey, _}, Version,
MasterSecret, Algorithm, {_, Hashes0})
when Algorithm == rsa;
- Algorithm == dh_rsa;
Algorithm == dhe_rsa ->
Hashes = calc_certificate_verify(Version, MasterSecret,
Algorithm, Hashes0),
@@ -319,11 +349,7 @@ key_exchange(client, {premaster_secret, Secret, {_, PublicKey, _}}) ->
EncPremasterSecret =
encrypted_premaster_secret(Secret, PublicKey),
#client_key_exchange{exchange_keys = EncPremasterSecret};
-key_exchange(client, fixed_diffie_hellman) ->
- #client_key_exchange{exchange_keys =
- #client_diffie_hellman_public{
- dh_public = <<>>
- }};
+
key_exchange(client, {dh, <<?UINT32(Len), PublicKey:Len/binary>>}) ->
#client_key_exchange{
exchange_keys = #client_diffie_hellman_public{
@@ -349,10 +375,7 @@ key_exchange(server, {dh, {<<?UINT32(_), PublicKey/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{}.
+ signed_params = Signed}.
%%--------------------------------------------------------------------
%% Function: master_secret(Version, Session/PremasterSecret,
@@ -525,7 +548,109 @@ select_session(Hello, Port, Session, Version,
false ->
{resumed, CacheCb:lookup(Cache, {Port, SessionId})}
end.
-
+
+
+cipher_suites(Suites, false) ->
+ [?TLS_EMPTY_RENEGOTIATION_INFO_SCSV | Suites];
+cipher_suites(Suites, true) ->
+ Suites.
+
+renegotiation_info(client, _, false) ->
+ #renegotiation_info{renegotiated_connection = undefined};
+renegotiation_info(server, ConnectionStates, false) ->
+ CS = ssl_record:current_connection_state(ConnectionStates, read),
+ case CS#connection_state.secure_renegotiation of
+ true ->
+ #renegotiation_info{renegotiated_connection = ?byte(0)};
+ false ->
+ #renegotiation_info{renegotiated_connection = undefined}
+ end;
+renegotiation_info(client, ConnectionStates, true) ->
+ CS = ssl_record:current_connection_state(ConnectionStates, read),
+ case CS#connection_state.secure_renegotiation of
+ true ->
+ Data = CS#connection_state.client_verify_data,
+ #renegotiation_info{renegotiated_connection = Data};
+ false ->
+ #renegotiation_info{renegotiated_connection = undefined}
+ end;
+
+renegotiation_info(server, ConnectionStates, true) ->
+ CS = ssl_record:current_connection_state(ConnectionStates, read),
+ case CS#connection_state.secure_renegotiation of
+ true ->
+ CData = CS#connection_state.client_verify_data,
+ SData =CS#connection_state.server_verify_data,
+ #renegotiation_info{renegotiated_connection = <<CData/binary, SData/binary>>};
+ false ->
+ #renegotiation_info{renegotiated_connection = undefined}
+ end.
+
+handle_renegotiation_info(_, #renegotiation_info{renegotiated_connection = ?byte(0)},
+ ConnectionStates, false, _, _) ->
+ {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)};
+
+handle_renegotiation_info(server, undefined, ConnectionStates, _, _, CipherSuites) ->
+ case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
+ true ->
+ {ok, ssl_record:set_renegotiation_flag(true, ConnectionStates)};
+ false ->
+ {ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)}
+ end;
+
+handle_renegotiation_info(_, undefined, ConnectionStates, false, _, _) ->
+ {ok, ssl_record:set_renegotiation_flag(false, ConnectionStates)};
+
+handle_renegotiation_info(client, #renegotiation_info{renegotiated_connection = ClientServerVerify},
+ ConnectionStates, true, _, _) ->
+ CS = ssl_record:current_connection_state(ConnectionStates, read),
+ CData = CS#connection_state.client_verify_data,
+ SData = CS#connection_state.server_verify_data,
+ case <<CData/binary, SData/binary>> == ClientServerVerify of
+ true ->
+ {ok, ConnectionStates};
+ false ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)
+ end;
+handle_renegotiation_info(server, #renegotiation_info{renegotiated_connection = ClientVerify},
+ ConnectionStates, true, _, CipherSuites) ->
+
+ case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
+ true ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE);
+ false ->
+ CS = ssl_record:current_connection_state(ConnectionStates, read),
+ Data = CS#connection_state.client_verify_data,
+ case Data == ClientVerify of
+ true ->
+ {ok, ConnectionStates};
+ false ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)
+ end
+ end;
+
+handle_renegotiation_info(client, undefined, ConnectionStates, true, SecureRenegotation, _) ->
+ handle_renegotiation_info(ConnectionStates, SecureRenegotation);
+
+handle_renegotiation_info(server, undefined, ConnectionStates, true, SecureRenegotation, CipherSuites) ->
+ case is_member(?TLS_EMPTY_RENEGOTIATION_INFO_SCSV, CipherSuites) of
+ true ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE);
+ false ->
+ handle_renegotiation_info(ConnectionStates, SecureRenegotation)
+ end.
+
+handle_renegotiation_info(ConnectionStates, SecureRenegotation) ->
+ CS = ssl_record:current_connection_state(ConnectionStates, read),
+ case {SecureRenegotation, CS#connection_state.secure_renegotiation} of
+ {_, true} ->
+ ?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE);
+ {true, false} ->
+ ?ALERT_REC(?FATAL, ?NO_RENEGOTIATION);
+ {false, false} ->
+ {ok, ConnectionStates}
+ end.
+
%% Update pending connection states with parameters exchanged via
%% hello messages
%% NOTE : Role is the role of the receiver of the hello message
@@ -597,12 +722,11 @@ master_secret(Version, MasterSecret, #security_parameters{
hash_size = HashSize,
key_material_length = KML,
expanded_key_material_length = EKML,
- iv_size = IVS,
- exportable = Exportable},
+ iv_size = IVS},
ConnectionStates, Role) ->
{ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
ServerWriteKey, ClientIV, ServerIV} =
- setup_keys(Version, Exportable, MasterSecret, ServerRandom,
+ setup_keys(Version, MasterSecret, ServerRandom,
ClientRandom, HashSize, KML, EKML, IVS),
?DBG_HEX(ClientWriteKey),
?DBG_HEX(ClientIV),
@@ -636,40 +760,55 @@ dec_hs(?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor),
random = ssl_ssl2:client_random(ChallengeData, CDLength),
session_id = 0,
cipher_suites = from_3bytes(CipherSuites),
- compression_methods = [?NULL]
+ compression_methods = [?NULL],
+ renegotiation_info = undefined
};
dec_hs(?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID:SID_length/binary,
?UINT16(Cs_length), CipherSuites:Cs_length/binary,
?BYTE(Cm_length), Comp_methods:Cm_length/binary,
- _FutureCompatData/binary>>,
+ Extensions/binary>>,
_, _) ->
+
+ RenegotiationInfo = proplists:get_value(renegotiation_info, dec_hello_extensions(Extensions),
+ undefined),
#client_hello{
client_version = {Major,Minor},
random = Random,
session_id = Session_ID,
cipher_suites = from_2bytes(CipherSuites),
- compression_methods = Comp_methods
+ compression_methods = Comp_methods,
+ renegotiation_info = RenegotiationInfo
};
+
dec_hs(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID:SID_length/binary,
- Cipher_suite:2/binary, ?BYTE(Comp_method)>>, _, _) ->
+ Cipher_suite:2/binary, ?BYTE(Comp_method)>>, _, _) ->
#server_hello{
server_version = {Major,Minor},
random = Random,
session_id = Session_ID,
cipher_suite = Cipher_suite,
- compression_method = Comp_method
- };
+ compression_method = Comp_method,
+ renegotiation_info = undefined};
+
+dec_hs(?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
+ ?BYTE(SID_length), Session_ID:SID_length/binary,
+ Cipher_suite:2/binary, ?BYTE(Comp_method),
+ ?UINT16(ExtLen), Extensions:ExtLen/binary>>, _, _) ->
+
+ RenegotiationInfo = proplists:get_value(renegotiation_info, dec_hello_extensions(Extensions, []),
+ undefined),
+ #server_hello{
+ server_version = {Major,Minor},
+ random = Random,
+ session_id = Session_ID,
+ cipher_suite = Cipher_suite,
+ compression_method = Comp_method,
+ renegotiation_info = RenegotiationInfo};
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,
- ?UINT16(_), Sig/binary>>,
- ?KEY_EXCHANGE_RSA, _) ->
- #server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod,
- rsa_exponent = Exp},
- signed_params = Sig};
+
dec_hs(?SERVER_KEY_EXCHANGE, <<?UINT16(PLen), P:PLen/binary,
?UINT16(GLen), G:GLen/binary,
?UINT16(YLen), Y:YLen/binary,
@@ -696,8 +835,7 @@ dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(_), PKEPMS/binary>>,
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));
+ throw(?ALERT_REC(?FATAL, ?UNSUPPORTED_CERTIFICATE));
dec_hs(?CLIENT_KEY_EXCHANGE, <<?UINT16(DH_YLen), DH_Y:DH_YLen/binary>>,
?KEY_EXCHANGE_DIFFIE_HELLMAN, _) ->
#client_key_exchange{exchange_keys =
@@ -707,6 +845,32 @@ dec_hs(?FINISHED, VerifyData, _, _) ->
dec_hs(_, _, _, _) ->
throw(?ALERT_REC(?FATAL, ?HANDSHAKE_FAILURE)).
+dec_hello_extensions(<<>>) ->
+ [];
+dec_hello_extensions(<<?UINT16(ExtLen), Extensions:ExtLen/binary>>) ->
+ dec_hello_extensions(Extensions, []);
+dec_hello_extensions(_) ->
+ [].
+
+dec_hello_extensions(<<>>, Acc) ->
+ Acc;
+dec_hello_extensions(<<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info:Len/binary, Rest/binary>>, Acc) ->
+ RenegotiateInfo = case Len of
+ 1 -> % Initial handshake
+ Info; % should be <<0>> will be matched in handle_renegotiation_info
+ _ ->
+ VerifyLen = Len - 1,
+ <<?BYTE(VerifyLen), VerifyInfo/binary>> = Info,
+ VerifyInfo
+ end,
+ dec_hello_extensions(Rest, [{renegotiation_info,
+ #renegotiation_info{renegotiated_connection = RenegotiateInfo}} | Acc]);
+dec_hello_extensions(<<?UINT16(_), ?UINT16(Len), _Unknown:Len, Rest/binary>>, Acc) ->
+ dec_hello_extensions(Rest, Acc);
+%% Need this clause?
+dec_hello_extensions(_, Acc) ->
+ Acc.
+
encrypted_premaster_secret(Secret, RSAPublicKey) ->
try
PreMasterSecret = public_key:encrypt_public(Secret, RSAPublicKey,
@@ -743,45 +907,40 @@ certs_from_list(ACList) ->
enc_hs(#hello_request{}, _Version, _) ->
{?HELLO_REQUEST, <<>>};
-enc_hs(#client_hello{
- client_version = {Major, Minor},
- random = Random,
- session_id = SessionID,
- cipher_suites = CipherSuites,
- compression_methods = CompMethods}, _Version, _) ->
+enc_hs(#client_hello{client_version = {Major, Minor},
+ random = Random,
+ session_id = SessionID,
+ cipher_suites = CipherSuites,
+ compression_methods = CompMethods,
+ renegotiation_info = RenegotiationInfo}, _Version, _) ->
SIDLength = byte_size(SessionID),
BinCompMethods = list_to_binary(CompMethods),
CmLength = byte_size(BinCompMethods),
BinCipherSuites = list_to_binary(CipherSuites),
CsLength = byte_size(BinCipherSuites),
+ Extensions = hello_extensions(RenegotiationInfo),
+ ExtensionsBin = enc_hello_extensions(Extensions),
{?CLIENT_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SIDLength), SessionID/binary,
?UINT16(CsLength), BinCipherSuites/binary,
- ?BYTE(CmLength), BinCompMethods/binary>>};
-enc_hs(#server_hello{
- server_version = {Major, Minor},
- random = Random,
- session_id = Session_ID,
- cipher_suite = Cipher_suite,
- compression_method = Comp_method}, _Version, _) ->
+ ?BYTE(CmLength), BinCompMethods/binary, ExtensionsBin/binary>>};
+
+enc_hs(#server_hello{server_version = {Major, Minor},
+ random = Random,
+ session_id = Session_ID,
+ cipher_suite = Cipher_suite,
+ compression_method = Comp_method,
+ renegotiation_info = RenegotiationInfo}, _Version, _) ->
SID_length = byte_size(Session_ID),
+ Extensions = hello_extensions(RenegotiationInfo),
+ ExtensionsBin = enc_hello_extensions(Extensions),
{?SERVER_HELLO, <<?BYTE(Major), ?BYTE(Minor), Random:32/binary,
?BYTE(SID_length), Session_ID/binary,
- Cipher_suite/binary, ?BYTE(Comp_method)>>};
+ Cipher_suite/binary, ?BYTE(Comp_method), ExtensionsBin/binary>>};
enc_hs(#certificate{asn1_certificates = ASN1CertList}, _Version, _) ->
ASN1Certs = certs_from_list(ASN1CertList),
ACLen = erlang:iolist_size(ASN1Certs),
{?CERTIFICATE, <<?UINT24(ACLen), ASN1Certs:ACLen/binary>>};
-enc_hs(#server_key_exchange{params = #server_rsa_params{rsa_modulus = Mod,
- rsa_exponent = Exp},
- signed_params = SignedParams}, _Version, _) ->
- ModLen = byte_size(Mod),
- ExpLen = byte_size(Exp),
- SignedLen = byte_size(SignedParams),
- {?SERVER_KEY_EXCHANGE, <<?UINT16(ModLen),Mod/binary,
- ?UINT16(ExpLen), Exp/binary,
- ?UINT16(SignedLen), SignedParams/binary>>
- };
enc_hs(#server_key_exchange{params = #server_dh_params{
dh_p = P, dh_g = G, dh_y = Y},
signed_params = SignedParams}, _Version, _) ->
@@ -826,6 +985,29 @@ enc_bin_sig(BinSig) ->
Size = byte_size(BinSig),
<<?UINT16(Size), BinSig/binary>>.
+%% Renegotiation info, only current extension
+hello_extensions(#renegotiation_info{renegotiated_connection = undefined}) ->
+ [];
+hello_extensions(#renegotiation_info{} = Info) ->
+ [Info].
+
+enc_hello_extensions(Extensions) ->
+ enc_hello_extensions(Extensions, <<>>).
+enc_hello_extensions([], <<>>) ->
+ <<>>;
+enc_hello_extensions([], Acc) ->
+ Size = byte_size(Acc),
+ <<?UINT16(Size), Acc/binary>>;
+
+enc_hello_extensions([#renegotiation_info{renegotiated_connection = ?byte(0) = Info} | Rest], Acc) ->
+ Len = byte_size(Info),
+ enc_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), Info/binary, Acc/binary>>);
+
+enc_hello_extensions([#renegotiation_info{renegotiated_connection = Info} | Rest], Acc) ->
+ InfoLen = byte_size(Info),
+ Len = InfoLen +1,
+ enc_hello_extensions(Rest, <<?UINT16(?RENEGOTIATION_EXT), ?UINT16(Len), ?BYTE(InfoLen), Info/binary, Acc/binary>>).
+
init_hashes() ->
T = {crypto:md5_init(), crypto:sha_init()},
{T, T}.
@@ -868,16 +1050,11 @@ from_2bytes(<<?UINT16(N), Rest/binary>>, Acc) ->
certificate_types({KeyExchange, _, _, _})
when KeyExchange == rsa;
- KeyExchange == dh_dss;
- KeyExchange == dh_rsa;
KeyExchange == dhe_dss;
KeyExchange == dhe_rsa ->
<<?BYTE(?RSA_SIGN), ?BYTE(?DSS_SIGN)>>;
certificate_types(_) ->
- %%TODO: Is this a good default,
- %% is there a case where we like to request
- %% a RSA_FIXED_DH or DSS_FIXED_DH
<<?BYTE(?RSA_SIGN)>>.
certificate_authorities(CertDbRef) ->
@@ -896,7 +1073,7 @@ 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
+ case ssl_manager:issuer_candidate(PrevKey) of
no_more_candidates ->
lists:reverse(Acc);
{{CertDbRef, _, _} = Key, Cert} ->
@@ -920,20 +1097,15 @@ calc_master_secret({3,N},PremasterSecret, ClientRandom, ServerRandom)
when N == 1; N == 2 ->
ssl_tls1:master_secret(PremasterSecret, ClientRandom, ServerRandom).
-setup_keys({3,0}, Exportable, MasterSecret,
+setup_keys({3,0}, MasterSecret,
ServerRandom, ClientRandom, HashSize, KML, EKML, IVS) ->
- ssl_ssl3:setup_keys(Exportable, MasterSecret, ServerRandom,
+ ssl_ssl3:setup_keys(MasterSecret, ServerRandom,
ClientRandom, HashSize, KML, EKML, IVS);
-setup_keys({3,1}, _Exportable, MasterSecret,
+setup_keys({3,1}, MasterSecret,
ServerRandom, ClientRandom, HashSize, KML, _EKML, IVS) ->
ssl_tls1:setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
- KML, IVS);
-
-setup_keys({3,2}, _Exportable, MasterSecret,
- ServerRandom, ClientRandom, HashSize, KML, _EKML, _IVS) ->
- ssl_tls1:setup_keys(MasterSecret, ServerRandom,
- ClientRandom, HashSize, KML).
+ KML, IVS).
calc_finished({3, 0}, Role, MasterSecret, Hashes) ->
ssl_ssl3:finished(Role, MasterSecret, Hashes);
@@ -948,7 +1120,6 @@ calc_certificate_verify({3, N}, _, Algorithm, Hashes)
ssl_tls1:certificate_verify(Algorithm, Hashes).
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),
@@ -960,9 +1131,7 @@ server_key_exchange_hash(Algorithm, Value) when Algorithm == rsa;
<<MD5/binary, SHA/binary>>;
-server_key_exchange_hash(Algorithm, Value) when Algorithm == dh_dss;
- Algorithm == dhe_dss ->
-
+server_key_exchange_hash(dhe_dss, Value) ->
SHAContext = crypto:sha_init(),
NewSHAContext = crypto:sha_update(SHAContext, Value),
crypto:sha_final(NewSHAContext).
@@ -970,9 +1139,9 @@ server_key_exchange_hash(Algorithm, Value) when Algorithm == dh_dss;
sig_alg(dh_anon) ->
?SIGNATURE_ANONYMOUS;
-sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa; Alg == dh_rsa ->
+sig_alg(Alg) when Alg == dhe_rsa; Alg == rsa ->
?SIGNATURE_RSA;
-sig_alg(Alg) when Alg == dh_dss; Alg == dhe_dss ->
+sig_alg(dhe_dss) ->
?SIGNATURE_DSA;
sig_alg(_) ->
?NULL.
diff --git a/lib/ssl/src/ssl_handshake.hrl b/lib/ssl/src/ssl_handshake.hrl
index 889d39f2af..74fba3786c 100644
--- a/lib/ssl/src/ssl_handshake.hrl
+++ b/lib/ssl/src/ssl_handshake.hrl
@@ -81,7 +81,8 @@
random,
session_id, % opaque SessionID<0..32>
cipher_suites, % cipher_suites<2..2^16-1>
- compression_methods % compression_methods<1..2^8-1>
+ compression_methods, % compression_methods<1..2^8-1>,
+ renegotiation_info
}).
-record(server_hello, {
@@ -89,7 +90,8 @@
random,
session_id, % opaque SessionID<0..32>
cipher_suite, % cipher_suites
- compression_method % compression_method
+ compression_method, % compression_method
+ renegotiation_info
}).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -195,6 +197,15 @@
verify_data %opaque verify_data[12]
}).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Renegotiation info RFC 5746 section 3.2
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-define(RENEGOTIATION_EXT, 16#ff01).
+
+-record(renegotiation_info,{
+ renegotiated_connection
+ }).
+
-endif. % -ifdef(ssl_handshake).
diff --git a/lib/ssl/src/ssl_internal.hrl b/lib/ssl/src/ssl_internal.hrl
index 8d19abfe1e..fdc0c33750 100644
--- a/lib/ssl/src/ssl_internal.hrl
+++ b/lib/ssl/src/ssl_internal.hrl
@@ -75,6 +75,7 @@
%% will be reused if possible.
reuse_sessions, % boolean()
renegotiate_at,
+ secure_renegotiate,
debug %
}).
diff --git a/lib/ssl/src/ssl_manager.erl b/lib/ssl/src/ssl_manager.erl
index 0151426d43..19bdcfa1f5 100644
--- a/lib/ssl/src/ssl_manager.erl
+++ b/lib/ssl/src/ssl_manager.erl
@@ -27,7 +27,7 @@
%% Internal application API
-export([start_link/0, start_link/1,
connection_init/2, cache_pem_file/1,
- lookup_trusted_cert/3, client_session_id/3, server_session_id/3,
+ lookup_trusted_cert/3, issuer_candidate/1, client_session_id/3, server_session_id/3,
register_session/2, register_session/3, invalidate_session/2,
invalidate_session/3]).
@@ -85,13 +85,20 @@ cache_pem_file(File) ->
%% Function:
%% Description:
%%--------------------------------------------------------------------
-lookup_trusted_cert(SerialNumber, Issuer, Ref) ->
+lookup_trusted_cert(Ref, SerialNumber, Issuer) ->
ssl_certificate_db:lookup_trusted_cert(Ref, SerialNumber, Issuer).
%%--------------------------------------------------------------------
%% Function:
%% Description:
%%--------------------------------------------------------------------
+issuer_candidate(PrevCandidateKey) ->
+ ssl_certificate_db:issuer_candidate(PrevCandidateKey).
+
+%%--------------------------------------------------------------------
+%% Function:
+%% Description:
+%%--------------------------------------------------------------------
client_session_id(Host, Port, SslOpts) ->
call({client_session_id, Host, Port, SslOpts}).
@@ -133,19 +140,19 @@ invalidate_session(Port, Session) ->
%% {stop, Reason}
%% Description: Initiates the server
%%--------------------------------------------------------------------
-init(Opts) ->
+init([Opts]) ->
process_flag(trap_exit, true),
- CacheCb = proplists:get_value(session_cache, Opts, ssl_session_cache),
+ CacheCb = proplists:get_value(session_cb, Opts, ssl_session_cache),
SessionLifeTime =
proplists:get_value(session_lifetime, Opts, ?'24H_in_sec'),
CertDb = ssl_certificate_db:create(),
- SessionCache = CacheCb:init(),
+ SessionCache = CacheCb:init(proplists:get_value(session_cb_init_args, Opts, [])),
Timer = erlang:send_after(SessionLifeTime * 1000,
self(), validate_sessions),
{ok, #state{certificate_db = CertDb,
session_cache = SessionCache,
session_cache_cb = CacheCb,
- session_lifetime = SessionLifeTime ,
+ session_lifetime = SessionLifeTime,
session_validation_timer = Timer}}.
%%--------------------------------------------------------------------
@@ -172,10 +179,8 @@ handle_call({{connection_init, TrustedcertsFile, _Role}, Pid}, _From,
{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()}}
+ _:Reason ->
+ {error, Reason}
end,
{reply, Result, State};
@@ -197,14 +202,10 @@ 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 _:{badmatch, Reason} ->
- {reply, Reason, State};
- _:Reason ->
+ catch
+ _:Reason ->
{reply, {error, Reason}, State}
- end;
-
-handle_call(_,_, State) ->
- {reply, ok, State}.
+ end.
%%--------------------------------------------------------------------
%% Function: handle_cast(Msg, State) -> {noreply, State} |
%% {noreply, State, Timeout} |
@@ -332,7 +333,7 @@ init_session_validator([Cache, CacheCb, LifeTime]) ->
CacheCb:foldl(fun session_validation/2,
LifeTime, Cache).
-session_validation({{Host, Port, _}, Session}, LifeTime) ->
+session_validation({{{Host, Port}, _}, Session}, LifeTime) ->
validate_session(Host, Port, Session, LifeTime),
LifeTime;
session_validation({{Port, _}, Session}, LifeTime) ->
diff --git a/lib/ssl/src/ssl_record.erl b/lib/ssl/src/ssl_record.erl
index da48f049f6..7c4b0ee959 100644
--- a/lib/ssl/src/ssl_record.erl
+++ b/lib/ssl/src/ssl_record.erl
@@ -29,6 +29,7 @@
-include("ssl_internal.hrl").
-include("ssl_alert.hrl").
-include("ssl_handshake.hrl").
+-include("ssl_cipher.hrl").
-include("ssl_debug.hrl").
%% Connection state handling
@@ -38,7 +39,10 @@
set_mac_secret/4,
set_master_secret/2,
activate_pending_connection_state/2,
- set_pending_cipher_state/4]).
+ set_pending_cipher_state/4,
+ set_renegotiation_flag/2,
+ set_client_verify_data/3,
+ set_server_verify_data/3]).
%% Handling of incoming data
-export([get_tls_records/2]).
@@ -175,6 +179,98 @@ set_master_secret(MasterSecret,
master_secret = MasterSecret}},
States#connection_states{pending_read = Read1, pending_write = Write1}.
+%%--------------------------------------------------------------------
+%% Function: set_renegotiation_flag(Flag, States) ->
+%% #connection_states{}
+%% Flag = boolean()
+%% States = #connection_states{}
+%%
+%% Set master_secret in pending connection states
+%%--------------------------------------------------------------------
+set_renegotiation_flag(Flag, #connection_states{
+ current_read = CurrentRead0,
+ current_write = CurrentWrite0,
+ pending_read = PendingRead0,
+ pending_write = PendingWrite0}
+ = ConnectionStates) ->
+ CurrentRead = CurrentRead0#connection_state{secure_renegotiation = Flag},
+ CurrentWrite = CurrentWrite0#connection_state{secure_renegotiation = Flag},
+ PendingRead = PendingRead0#connection_state{secure_renegotiation = Flag},
+ PendingWrite = PendingWrite0#connection_state{secure_renegotiation = Flag},
+ ConnectionStates#connection_states{current_read = CurrentRead,
+ current_write = CurrentWrite,
+ pending_read = PendingRead,
+ pending_write = PendingWrite}.
+
+%%--------------------------------------------------------------------
+%% Function: set_client_verify_data(State, Data, States) ->
+%% #connection_states{}
+%% State = atom()
+%% Data = binary()
+%% States = #connection_states{}
+%%
+%% Set verify data in connection states.
+%%--------------------------------------------------------------------
+set_client_verify_data(current_read, Data,
+ #connection_states{current_read = CurrentRead0,
+ pending_write = PendingWrite0}
+ = ConnectionStates) ->
+ CurrentRead = CurrentRead0#connection_state{client_verify_data = Data},
+ PendingWrite = PendingWrite0#connection_state{client_verify_data = Data},
+ ConnectionStates#connection_states{current_read = CurrentRead,
+ pending_write = PendingWrite};
+set_client_verify_data(current_write, Data,
+ #connection_states{pending_read = PendingRead0,
+ current_write = CurrentWrite0}
+ = ConnectionStates) ->
+ PendingRead = PendingRead0#connection_state{client_verify_data = Data},
+ CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data},
+ ConnectionStates#connection_states{pending_read = PendingRead,
+ current_write = CurrentWrite};
+set_client_verify_data(current_both, Data,
+ #connection_states{current_read = CurrentRead0,
+ current_write = CurrentWrite0}
+ = ConnectionStates) ->
+ CurrentRead = CurrentRead0#connection_state{client_verify_data = Data},
+ CurrentWrite = CurrentWrite0#connection_state{client_verify_data = Data},
+ ConnectionStates#connection_states{current_read = CurrentRead,
+ current_write = CurrentWrite}.
+
+%%--------------------------------------------------------------------
+%% Function: set_server_verify_data(State, Data, States) ->
+%% #connection_states{}
+%% State = atom()
+%% Data = binary()
+%% States = #connection_states{}
+%%
+%% Set verify data in pending connection states.
+%%--------------------------------------------------------------------
+set_server_verify_data(current_write, Data,
+ #connection_states{pending_read = PendingRead0,
+ current_write = CurrentWrite0}
+ = ConnectionStates) ->
+ PendingRead = PendingRead0#connection_state{server_verify_data = Data},
+ CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data},
+ ConnectionStates#connection_states{pending_read = PendingRead,
+ current_write = CurrentWrite};
+
+set_server_verify_data(current_read, Data,
+ #connection_states{current_read = CurrentRead0,
+ pending_write = PendingWrite0}
+ = ConnectionStates) ->
+ CurrentRead = CurrentRead0#connection_state{server_verify_data = Data},
+ PendingWrite = PendingWrite0#connection_state{server_verify_data = Data},
+ ConnectionStates#connection_states{current_read = CurrentRead,
+ pending_write = PendingWrite};
+
+set_server_verify_data(current_both, Data,
+ #connection_states{current_read = CurrentRead0,
+ current_write = CurrentWrite0}
+ = ConnectionStates) ->
+ CurrentRead = CurrentRead0#connection_state{server_verify_data = Data},
+ CurrentWrite = CurrentWrite0#connection_state{server_verify_data = Data},
+ ConnectionStates#connection_states{current_read = CurrentRead,
+ current_write = CurrentWrite}.
%%--------------------------------------------------------------------
%% Function: activate_pending_connection_state(States, Type) ->
@@ -191,7 +287,9 @@ activate_pending_connection_state(States =
NewCurrent = Pending#connection_state{sequence_number = 0},
SecParams = Pending#connection_state.security_parameters,
ConnectionEnd = SecParams#security_parameters.connection_end,
- NewPending = empty_connection_state(ConnectionEnd),
+ EmptyPending = empty_connection_state(ConnectionEnd),
+ SecureRenegotation = NewCurrent#connection_state.secure_renegotiation,
+ NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation},
States#connection_states{current_read = NewCurrent,
pending_read = NewPending
};
@@ -202,7 +300,9 @@ activate_pending_connection_state(States =
NewCurrent = Pending#connection_state{sequence_number = 0},
SecParams = Pending#connection_state.security_parameters,
ConnectionEnd = SecParams#security_parameters.connection_end,
- NewPending = empty_connection_state(ConnectionEnd),
+ EmptyPending = empty_connection_state(ConnectionEnd),
+ SecureRenegotation = NewCurrent#connection_state.secure_renegotiation,
+ NewPending = EmptyPending#connection_state{secure_renegotiation = SecureRenegotation},
States#connection_states{current_write = NewCurrent,
pending_write = NewPending
}.
@@ -311,16 +411,14 @@ protocol_version(tlsv1) ->
{3, 1};
protocol_version(sslv3) ->
{3, 0};
-protocol_version(sslv2) ->
+protocol_version(sslv2) -> %% Backwards compatibility
{2, 0};
protocol_version({3, 2}) ->
'tlsv1.1';
protocol_version({3, 1}) ->
tlsv1;
protocol_version({3, 0}) ->
- sslv3;
-protocol_version({2, 0}) ->
- sslv2.
+ sslv3.
%%--------------------------------------------------------------------
%% Function: protocol_version(Version1, Version2) -> #protocol_version{}
%% Version1 = Version2 = #protocol_version{}
@@ -368,7 +466,7 @@ highest_protocol_version(_, [Version | Rest]) ->
%%--------------------------------------------------------------------
supported_protocol_versions() ->
Fun = fun(Version) ->
- protocol_version(Version)
+ protocol_version(Version)
end,
case application:get_env(ssl, protocol_version) of
undefined ->
@@ -376,11 +474,18 @@ supported_protocol_versions() ->
{ok, []} ->
lists:map(Fun, ?DEFAULT_SUPPORTED_VERSIONS);
{ok, Vsns} when is_list(Vsns) ->
- lists:map(Fun, Vsns);
+ Versions = lists:filter(fun is_acceptable_version/1, lists:map(Fun, Vsns)),
+ supported_protocol_versions(Versions);
{ok, Vsn} ->
- [Fun(Vsn)]
+ Versions = lists:filter(fun is_acceptable_version/1, [Fun(Vsn)]),
+ supported_protocol_versions(Versions)
end.
+supported_protocol_versions([]) ->
+ ?DEFAULT_SUPPORTED_VERSIONS;
+supported_protocol_versions([_|_] = Vsns) ->
+ Vsns.
+
%%--------------------------------------------------------------------
%% Function: is_acceptable_version(Version) -> true | false
%% Version = #protocol_version{}
@@ -412,13 +517,17 @@ decode_cipher_text(CipherText, ConnnectionStates0) ->
#connection_state{compression_state = CompressionS0,
security_parameters = SecParams} = ReadState0,
CompressAlg = SecParams#security_parameters.compression_algorithm,
- {Compressed, ReadState1} = decipher(CipherText, ReadState0),
- {Plain, CompressionS1} = uncompress(CompressAlg,
- Compressed, CompressionS0),
- ConnnectionStates = ConnnectionStates0#connection_states{
- current_read = ReadState1#connection_state{
- compression_state = CompressionS1}},
- {Plain, ConnnectionStates}.
+ case decipher(CipherText, ReadState0) of
+ {Compressed, ReadState1} ->
+ {Plain, CompressionS1} = uncompress(CompressAlg,
+ Compressed, CompressionS0),
+ ConnnectionStates = ConnnectionStates0#connection_states{
+ current_read = ReadState1#connection_state{
+ compression_state = CompressionS1}},
+ {Plain, ConnnectionStates};
+ #alert{} = Alert ->
+ Alert
+ end.
%%--------------------------------------------------------------------
%%% Internal functions
@@ -433,12 +542,10 @@ initial_connection_state(ConnectionEnd) ->
}.
initial_security_params(ConnectionEnd) ->
- #security_parameters{connection_end = ConnectionEnd,
- bulk_cipher_algorithm = ?NULL,
- mac_algorithm = ?NULL,
- compression_algorithm = ?NULL,
- cipher_type = ?NULL
- }.
+ SecParams = #security_parameters{connection_end = ConnectionEnd,
+ compression_algorithm = ?NULL},
+ ssl_cipher:security_parameters(?TLS_NULL_WITH_NULL_NULL,
+ SecParams).
empty_connection_state(ConnectionEnd) ->
SecParams = empty_security_params(ConnectionEnd),
@@ -544,29 +651,37 @@ encode_tls_cipher_text(Type, {MajVer, MinVer}, Fragment) ->
cipher(Type, Version, Fragment, CS0) ->
Length = erlang:iolist_size(Fragment),
- {Hash, CS1=#connection_state{cipher_state = CipherS0,
+ {MacHash, CS1=#connection_state{cipher_state = CipherS0,
security_parameters=
#security_parameters{bulk_cipher_algorithm =
BCA}
}} =
hash_and_bump_seqno(CS0, Type, Version, Length, Fragment),
?DBG_HEX(Fragment),
- {Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, Hash, Fragment),
+ {Ciphered, CipherS1} = ssl_cipher:cipher(BCA, CipherS0, MacHash, Fragment),
?DBG_HEX(Ciphered),
CS2 = CS1#connection_state{cipher_state=CipherS1},
{Ciphered, CS2}.
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?
+ BCA = SP#security_parameters.bulk_cipher_algorithm,
HashSz = SP#security_parameters.hash_size,
CipherS0 = CS0#connection_state.cipher_state,
- {T, Mac, CipherS1} = ssl_cipher:decipher(BCA, HashSz, CipherS0, Fragment),
- CS1 = CS0#connection_state{cipher_state = CipherS1},
- TLength = size(T),
- {Hash, CS2} = hash_and_bump_seqno(CS1, Type, Version, TLength, Fragment),
- ok = check_hash(Hash, Mac),
- {TLS#ssl_tls{fragment = T}, CS2}.
+ case ssl_cipher:decipher(BCA, HashSz, CipherS0, Fragment, Version) of
+ {T, Mac, CipherS1} ->
+ CS1 = CS0#connection_state{cipher_state = CipherS1},
+ TLength = size(T),
+ {MacHash, CS2} = hash_and_bump_seqno(CS1, Type, Version, TLength, T),
+ case is_correct_mac(Mac, MacHash) of
+ true ->
+ {TLS#ssl_tls{fragment = T}, CS2};
+ false ->
+ ?ALERT_REC(?FATAL, ?BAD_RECORD_MAC)
+ end;
+ #alert{} = Alert ->
+ Alert
+ end.
uncompress(?NULL, Data = #ssl_tls{type = _Type,
version = _Version,
@@ -587,10 +702,13 @@ hash_and_bump_seqno(#connection_state{sequence_number = SeqNo,
Length, Fragment),
{Hash, CS0#connection_state{sequence_number = SeqNo+1}}.
-check_hash(_, _) ->
- ok. %% TODO check this
+is_correct_mac(Mac, Mac) ->
+ true;
+is_correct_mac(_M,_H) ->
+ io:format("Mac ~p ~n Hash: ~p~n",[_M, _H]),
+ false.
-mac_hash(?NULL, {_,_}, _MacSecret, _SeqNo, _Type,
+mac_hash({_,_}, ?NULL, _MacSecret, _SeqNo, _Type,
_Length, _Fragment) ->
<<>>;
mac_hash({3, 0}, MacAlg, MacSecret, SeqNo, Type, Length, Fragment) ->
diff --git a/lib/ssl/src/ssl_record.hrl b/lib/ssl/src/ssl_record.hrl
index 362b7039d4..5fb0070b91 100644
--- a/lib/ssl/src/ssl_record.hrl
+++ b/lib/ssl/src/ssl_record.hrl
@@ -60,7 +60,11 @@
compression_state,
cipher_state,
mac_secret,
- sequence_number
+ sequence_number,
+ %% RFC 5746
+ secure_renegotiation,
+ client_verify_data,
+ server_verify_data
}).
-define(MAX_SEQENCE_NUMBER, 18446744073709552000). %% math:pow(2, 64) - 1 = 1.8446744073709552e19
diff --git a/lib/ssl/src/ssl_session_cache.erl b/lib/ssl/src/ssl_session_cache.erl
index 4a60892235..1f2d1fc7d3 100644
--- a/lib/ssl/src/ssl_session_cache.erl
+++ b/lib/ssl/src/ssl_session_cache.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%
%%
@@ -22,8 +22,8 @@
-behaviour(ssl_session_cache_api).
--export([init/0, terminate/1, lookup/2, update/3, delete/2, foldl/3,
- select_session/2]).
+-export([init/1, terminate/1, lookup/2, update/3, delete/2, foldl/3,
+ select_session/2]).
%%--------------------------------------------------------------------
%% Function: init() -> Cache
@@ -32,7 +32,7 @@
%%
%% Description: Return table reference. Called by ssl_manager process.
%%--------------------------------------------------------------------
-init() ->
+init(_) ->
ets:new(cache_name(), [set, protected]).
%%--------------------------------------------------------------------
diff --git a/lib/ssl/src/ssl_session_cache_api.erl b/lib/ssl/src/ssl_session_cache_api.erl
index d2e846e9fd..f8416bf327 100644
--- a/lib/ssl/src/ssl_session_cache_api.erl
+++ b/lib/ssl/src/ssl_session_cache_api.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%
%%
@@ -25,7 +25,7 @@
behaviour_info(callbacks) ->
[
- {init, 0},
+ {init, 1},
{terminate, 1},
{lookup, 2},
{update, 3},
diff --git a/lib/ssl/src/ssl_ssl3.erl b/lib/ssl/src/ssl_ssl3.erl
index df809ce275..1bf8c2b458 100644
--- a/lib/ssl/src/ssl_ssl3.erl
+++ b/lib/ssl/src/ssl_ssl3.erl
@@ -30,7 +30,7 @@
-include("ssl_record.hrl"). % MD5 and SHA
-export([master_secret/3, finished/3, certificate_verify/3,
- mac_hash/6, setup_keys/8,
+ mac_hash/6, setup_keys/7,
suites/0]).
-compile(inline).
@@ -76,7 +76,7 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) ->
<<MD5/binary, SHA/binary>>.
certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash})
- when Algorithm == rsa; Algorithm == dh_rsa; Algorithm == dhe_rsa ->
+ when Algorithm == rsa; Algorithm == dhe_rsa ->
%% md5_hash
%% MD5(master_secret + pad_2 +
%% MD5(handshake_messages + master_secret + pad_1));
@@ -88,8 +88,7 @@ certificate_verify(Algorithm, MasterSecret, {MD5Hash, SHAHash})
SHA = handshake_hash(?SHA, MasterSecret, undefined, SHAHash),
<<MD5/binary, SHA/binary>>;
-certificate_verify(Algorithm, MasterSecret, {_, SHAHash})
- when Algorithm == dh_dss; Algorithm == dhe_dss ->
+certificate_verify(dhe_dss, MasterSecret, {_, SHAHash}) ->
%% sha_hash
%% SHA(master_secret + pad_2 +
%% SHA(handshake_messages + master_secret + pad_1));
@@ -114,9 +113,7 @@ mac_hash(Method, Mac_write_secret, Seq_num, Type, Length, Fragment) ->
?DBG_HEX(Mac),
Mac.
-setup_keys(Exportable, MasterSecret, ServerRandom, ClientRandom,
- HS, KML, _EKML, IVS)
- when Exportable == no_export; Exportable == ignore ->
+setup_keys(MasterSecret, ServerRandom, ClientRandom, HS, KML, _EKML, IVS) ->
KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom,
2*(HS+KML+IVS)),
%% draft-ietf-tls-ssl-version3-00 - 6.2.2
@@ -137,47 +134,7 @@ setup_keys(Exportable, MasterSecret, ServerRandom, ClientRandom,
?DBG_HEX(ClientIV),
?DBG_HEX(ServerIV),
{ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
- ServerWriteKey, ClientIV, ServerIV};
-
-setup_keys(export, MasterSecret, ServerRandom, ClientRandom,
- HS, KML, EKML, IVS) ->
- KeyBlock = generate_keyblock(MasterSecret, ServerRandom, ClientRandom,
- 2*(HS+KML)),
- %% draft-ietf-tls-ssl-version3-00 - 6.2.2
- %% Exportable encryption algorithms (for which
- %% CipherSpec.is_exportable is true) require additional processing as
- %% follows to derive their final write keys:
-
- %% final_client_write_key = MD5(client_write_key +
- %% ClientHello.random +
- %% ServerHello.random);
- %% final_server_write_key = MD5(server_write_key +
- %% ServerHello.random +
- %% ClientHello.random);
-
- %% Exportable encryption algorithms derive their IVs from the random
- %% messages:
- %% client_write_IV = MD5(ClientHello.random + ServerHello.random);
- %% server_write_IV = MD5(ServerHello.random + ClientHello.random);
-
- <<ClientWriteMacSecret:HS/binary, ServerWriteMacSecret:HS/binary,
- ClientWriteKey:KML/binary, ServerWriteKey:KML/binary>> = KeyBlock,
- <<ClientIV:IVS/binary, _/binary>> =
- hash(?MD5, [ClientRandom, ServerRandom]),
- <<ServerIV:IVS/binary, _/binary>> =
- hash(?MD5, [ServerRandom, ClientRandom]),
- <<FinalClientWriteKey:EKML/binary, _/binary>> =
- hash(?MD5, [ClientWriteKey, ClientRandom, ServerRandom]),
- <<FinalServerWriteKey:EKML/binary, _/binary>> =
- hash(?MD5, [ServerWriteKey, ServerRandom, ClientRandom]),
- ?DBG_HEX(ClientWriteMacSecret),
- ?DBG_HEX(ServerWriteMacSecret),
- ?DBG_HEX(FinalClientWriteKey),
- ?DBG_HEX(FinalServerWriteKey),
- ?DBG_HEX(ClientIV),
- ?DBG_HEX(ServerIV),
- {ClientWriteMacSecret, ServerWriteMacSecret, FinalClientWriteKey,
- FinalServerWriteKey, ClientIV, ServerIV}.
+ ServerWriteKey, ClientIV, ServerIV}.
suites() ->
[
@@ -191,25 +148,12 @@ suites() ->
?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?
+ %%?TLS_DHE_DSS_WITH_RC4_128_SHA,
%% ?TLS_RSA_WITH_IDEA_CBC_SHA, Not supported: in later openssl version than OTP requires
-
?TLS_RSA_WITH_RC4_128_SHA,
?TLS_RSA_WITH_RC4_128_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
%%?TLS_DHE_DSS_WITH_RC4_128_SHA,
-
?TLS_RSA_WITH_DES_CBC_SHA
- %% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- %% ?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %%?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- %%?TLS_RSA_EXPORT_WITH_RC4_40_MD5
].
%%--------------------------------------------------------------------
@@ -269,8 +213,7 @@ handshake_hash(Method, MasterSecret, Sender, HandshakeHash) ->
hash(Method, [MasterSecret, pad_2(Method), InnerHash]).
get_sender(client) -> "CLNT";
-get_sender(server) -> "SRVR";
-get_sender(none) -> "".
+get_sender(server) -> "SRVR".
generate_keyblock(MasterSecret, ServerRandom, ClientRandom, WantedLength) ->
gen(MasterSecret, [MasterSecret, ServerRandom, ClientRandom],
diff --git a/lib/ssl/src/ssl_sup.erl b/lib/ssl/src/ssl_sup.erl
index bd5a02417a..b7cb5c3ab3 100644
--- a/lib/ssl/src/ssl_sup.erl
+++ b/lib/ssl/src/ssl_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%
%%
@@ -40,8 +40,7 @@ start_link() ->
%%%=========================================================================
%% init([]) -> {ok, {SupFlags, [ChildSpec]}}
%%
-init([]) ->
-
+init([]) ->
%% OLD ssl - moved start to ssl.erl only if old
%% ssl is acctualy run!
%%Child1 = {ssl_server, {ssl_server, start_link, []},
@@ -67,7 +66,7 @@ init([]) ->
session_and_cert_manager_child_spec() ->
Opts = manager_opts(),
Name = ssl_manager,
- StartFunc = {ssl_manager, start_link, Opts},
+ StartFunc = {ssl_manager, start_link, [Opts]},
Restart = permanent,
Shutdown = 4000,
Modules = [ssl_manager],
@@ -86,11 +85,12 @@ connection_manager_child_spec() ->
manager_opts() ->
CbOpts = case application:get_env(ssl, session_cb) of
- {ok, Cb} when is_atom(Cb) ->
- [{session_cb, Cb}];
- _ ->
- []
- end,
+ {ok, Cb} when is_atom(Cb) ->
+ InitArgs = session_cb_init_args(),
+ [{session_cb, Cb}, {session_cb_init_args, InitArgs}];
+ _ ->
+ []
+ end,
case application:get_env(ssl, session_lifetime) of
{ok, Time} when is_integer(Time) ->
[{session_lifetime, Time}| CbOpts];
@@ -98,3 +98,10 @@ manager_opts() ->
CbOpts
end.
+session_cb_init_args() ->
+ case application:get_env(ssl, session_cb_init_args) of
+ {ok, Args} when is_list(Args) ->
+ Args;
+ _ ->
+ []
+ end.
diff --git a/lib/ssl/src/ssl_tls1.erl b/lib/ssl/src/ssl_tls1.erl
index ce9a135168..900b8e166d 100644
--- a/lib/ssl/src/ssl_tls1.erl
+++ b/lib/ssl/src/ssl_tls1.erl
@@ -30,7 +30,7 @@
-include("ssl_debug.hrl").
-export([master_secret/3, finished/3, certificate_verify/2, mac_hash/7,
- setup_keys/5, setup_keys/6, suites/0]).
+ setup_keys/6, suites/0]).
%%====================================================================
%% Internal application API
@@ -58,14 +58,12 @@ finished(Role, MasterSecret, {MD5Hash, SHAHash}) ->
certificate_verify(Algorithm, {MD5Hash, SHAHash}) when Algorithm == rsa;
- Algorithm == dh_rsa;
Algorithm == dhe_rsa ->
MD5 = hash_final(?MD5, MD5Hash),
SHA = hash_final(?SHA, SHAHash),
<<MD5/binary, SHA/binary>>;
-certificate_verify(Algorithm, {_, SHAHash}) when Algorithm == dh_dss;
- Algorithm == dhe_dss ->
+certificate_verify(dhe_dss, {_, SHAHash}) ->
hash_final(?SHA, SHAHash).
setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
@@ -92,26 +90,27 @@ setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize,
{ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
ServerWriteKey, ClientIV, ServerIV}.
-setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen) ->
- %% RFC 4346 - 6.3. Key calculation
- %% key_block = PRF(SecurityParameters.master_secret,
- %% "key expansion",
- %% SecurityParameters.server_random +
- %% SecurityParameters.client_random);
- %% Then the key_block is partitioned as follows:
- %% client_write_MAC_secret[SecurityParameters.hash_size]
- %% server_write_MAC_secret[SecurityParameters.hash_size]
- %% client_write_key[SecurityParameters.key_material_length]
- %% server_write_key[SecurityParameters.key_material_length]
- WantedLength = 2 * (HashSize + KeyMatLen),
- KeyBlock = prf(MasterSecret, "key expansion",
- [ServerRandom, ClientRandom], WantedLength),
- <<ClientWriteMacSecret:HashSize/binary,
- ServerWriteMacSecret:HashSize/binary,
- ClientWriteKey:KeyMatLen/binary, ServerWriteKey:KeyMatLen/binary>>
- = KeyBlock,
- {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
- ServerWriteKey, undefined, undefined}.
+%% TLS v1.1 uncomment when supported.
+%% setup_keys(MasterSecret, ServerRandom, ClientRandom, HashSize, KeyMatLen) ->
+%% %% RFC 4346 - 6.3. Key calculation
+%% %% key_block = PRF(SecurityParameters.master_secret,
+%% %% "key expansion",
+%% %% SecurityParameters.server_random +
+%% %% SecurityParameters.client_random);
+%% %% Then the key_block is partitioned as follows:
+%% %% client_write_MAC_secret[SecurityParameters.hash_size]
+%% %% server_write_MAC_secret[SecurityParameters.hash_size]
+%% %% client_write_key[SecurityParameters.key_material_length]
+%% %% server_write_key[SecurityParameters.key_material_length]
+%% WantedLength = 2 * (HashSize + KeyMatLen),
+%% KeyBlock = prf(MasterSecret, "key expansion",
+%% [ServerRandom, ClientRandom], WantedLength),
+%% <<ClientWriteMacSecret:HashSize/binary,
+%% ServerWriteMacSecret:HashSize/binary,
+%% ClientWriteKey:KeyMatLen/binary, ServerWriteKey:KeyMatLen/binary>>
+%% = KeyBlock,
+%% {ClientWriteMacSecret, ServerWriteMacSecret, ClientWriteKey,
+%% ServerWriteKey, undefined, undefined}.
mac_hash(Method, Mac_write_secret, Seq_num, Type, {Major, Minor},
Length, Fragment) ->
@@ -140,30 +139,18 @@ suites() ->
%%?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_DHE_DSS_WITH_3DES_EDE_CBC_SHA,
?TLS_RSA_WITH_3DES_EDE_CBC_SHA,
?TLS_DHE_RSA_WITH_AES_128_CBC_SHA,
- %% ?TLS_DHE_DSS_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?
- %% ?TLS_RSA_WITH_IDEA_CBC_SHA,
+ %%?TLS_DHE_DSS_WITH_RC4_128_SHA,
+ %%?TLS_RSA_WITH_IDEA_CBC_SHA,
?TLS_RSA_WITH_RC4_128_SHA,
?TLS_RSA_WITH_RC4_128_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
- %%?TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
- %%?TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
- %%?TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
- %%?TLS_DHE_DSS_WITH_RC4_128_SHA,
- %%?TLS_DHE_RSA_WITH_DES_CBC_SHA,
- %% EDH-DSS-DES-CBC-SHA TODO: ??
+ ?TLS_DHE_RSA_WITH_DES_CBC_SHA,
+ %%TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
?TLS_RSA_WITH_DES_CBC_SHA
- %% ?TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %% ?TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA,
- %%?TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,
- %%?TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5,
- %%?TLS_RSA_EXPORT_WITH_RC4_40_MD5
].
%%--------------------------------------------------------------------
@@ -245,7 +232,3 @@ hash_final(?MD5, Conntext) ->
crypto:md5_final(Conntext);
hash_final(?SHA, Conntext) ->
crypto:sha_final(Conntext).
-
-
-
-
diff --git a/lib/ssl/test/ssl.cover b/lib/ssl/test/ssl.cover
index 138bf96b9d..e8daa363c5 100644
--- a/lib/ssl/test/ssl.cover
+++ b/lib/ssl/test/ssl.cover
@@ -3,5 +3,17 @@
'PKIX1Explicit88',
'PKIX1Implicit88',
'PKIXAttributeCertificate',
- 'SSL-PKIX']}.
+ 'SSL-PKIX',
+ ssl_pem,
+ ssl_pkix,
+ ssl_base64,
+ ssl_broker,
+ ssl_broker_int,
+ ssl_broker_sup,
+ ssl_debug,
+ ssl_server,
+ ssl_prim,
+ inet_ssl_dist,
+ 'OTP-PKIX'
+ ]}.
diff --git a/lib/ssl/test/ssl_basic_SUITE.erl b/lib/ssl/test/ssl_basic_SUITE.erl
index 3ee82d990b..ad87cfcba1 100644
--- a/lib/ssl/test/ssl_basic_SUITE.erl
+++ b/lib/ssl/test/ssl_basic_SUITE.erl
@@ -27,17 +27,17 @@
-include("test_server.hrl").
-include("test_server_line.hrl").
-include_lib("public_key/include/public_key.hrl").
+-include("ssl_alert.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,
+-export([init/1, terminate/1, lookup/2, update/3,
delete/2, foldl/3, select_session/2]).
%% Test server callback functions
@@ -83,11 +83,11 @@ end_per_suite(_Config) ->
%% Description: Initialization before each test case
%%--------------------------------------------------------------------
init_per_testcase(session_cache_process_list, Config) ->
- init_customized_session_cache(Config);
+ init_customized_session_cache(list, Config);
init_per_testcase(session_cache_process_mnesia, Config) ->
mnesia:start(),
- init_customized_session_cache(Config);
+ init_customized_session_cache(mnesia, Config);
init_per_testcase(reuse_session_expired, Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
@@ -98,17 +98,49 @@ init_per_testcase(reuse_session_expired, Config0) ->
ssl:start(),
[{watchdog, Dog} | Config];
+init_per_testcase(no_authority_key_identifier, Config) ->
+ %% Clear cach so that root cert will not
+ %% be found.
+ ssl:stop(),
+ ssl:start(),
+ Config;
+
+init_per_testcase(TestCase, Config) when TestCase == ciphers_ssl3;
+ TestCase == ciphers_ssl3_openssl_names ->
+ ssl:stop(),
+ application:load(ssl),
+ application:set_env(ssl, protocol_version, sslv3),
+ ssl:start(),
+ Config;
+
+init_per_testcase(protocol_versions, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ %% For backwards compatibility sslv2 should be filtered out.
+ application:set_env(ssl, protocol_version, [sslv2, sslv3, tlsv1]),
+ ssl:start(),
+ Config;
+
+init_per_testcase(empty_protocol_versions, Config) ->
+ ssl:stop(),
+ application:load(ssl),
+ %% For backwards compatibility sslv2 should be filtered out.
+ application:set_env(ssl, protocol_version, []),
+ ssl:start(),
+ Config;
+
init_per_testcase(_TestCase, Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
Dog = test_server:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+ [{watchdog, Dog} | Config].
-init_customized_session_cache(Config0) ->
+init_customized_session_cache(Type, Config0) ->
Config = lists:keydelete(watchdog, 1, Config0),
Dog = test_server:timetrap(?TIMEOUT),
ssl:stop(),
application:load(ssl),
application:set_env(ssl, session_cb, ?MODULE),
+ application:set_env(ssl, session_cb_init_args, [Type]),
ssl:start(),
[{watchdog, Dog} | Config].
@@ -125,11 +157,20 @@ end_per_testcase(session_cache_process_list, Config) ->
end_per_testcase(default_action, Config);
end_per_testcase(session_cache_process_mnesia, Config) ->
application:unset_env(ssl, session_cb),
+ application:unset_env(ssl, session_cb_init_args),
mnesia:stop(),
+ ssl:stop(),
+ ssl:start(),
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) when TestCase == ciphers_ssl3;
+ TestCase == ciphers_ssl3_openssl_names;
+ TestCase == protocol_versions;
+ TestCase == empty_protocol_versions->
+ application:unset_env(ssl, protocol_version),
+ end_per_testcase(default_action, Config);
end_per_testcase(_TestCase, Config) ->
Dog = ?config(watchdog, Config),
case Dog of
@@ -151,29 +192,31 @@ all(doc) ->
["Test the basic ssl functionality"];
all(suite) ->
- [app, connection_info, controlling_process, controller_dies,
- client_closes_socket,
- 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
+ [app, alerts, connection_info, protocol_versions,
+ empty_protocol_versions, controlling_process, controller_dies,
+ client_closes_socket, 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, ciphers_ssl3,
+ ciphers_openssl_names, 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_renegotiate_reused_session,
+ server_renegotiate_reused_session, client_no_wrap_sequence_number,
+ server_no_wrap_sequence_number, extended_key_usage,
+ validate_extensions_fun, no_authority_key_identifier,
+ invalid_signature_client, invalid_signature_server, cert_expired
].
%% Test cases starts here.
@@ -184,7 +227,31 @@ app(suite) ->
[];
app(Config) when is_list(Config) ->
ok = test_server:app_test(ssl).
-
+%%--------------------------------------------------------------------
+alerts(doc) ->
+ "Test ssl_alert:alert_txt/1";
+alerts(suite) ->
+ [];
+alerts(Config) when is_list(Config) ->
+ Descriptions = [?CLOSE_NOTIFY, ?UNEXPECTED_MESSAGE, ?BAD_RECORD_MAC,
+ ?DECRYPTION_FAILED, ?RECORD_OVERFLOW, ?DECOMPRESSION_FAILURE,
+ ?HANDSHAKE_FAILURE, ?BAD_CERTIFICATE, ?UNSUPPORTED_CERTIFICATE,
+ ?CERTIFICATE_REVOKED,?CERTIFICATE_EXPIRED, ?CERTIFICATE_UNKNOWN,
+ ?ILLEGAL_PARAMETER, ?UNKNOWN_CA, ?ACCESS_DENIED, ?DECODE_ERROR,
+ ?DECRYPT_ERROR, ?EXPORT_RESTRICTION, ?PROTOCOL_VERSION,
+ ?INSUFFICIENT_SECURITY, ?INTERNAL_ERROR, ?USER_CANCELED,
+ ?NO_RENEGOTIATION],
+ Alerts = [?ALERT_REC(?WARNING, ?CLOSE_NOTIFY) |
+ [?ALERT_REC(?FATAL, Desc) || Desc <- Descriptions]],
+ lists:foreach(fun(Alert) ->
+ case ssl_alert:alert_txt(Alert) of
+ Txt when is_list(Txt) ->
+ ok;
+ Other ->
+ test_server:fail({unexpected, Other})
+ end
+ end, Alerts).
+%%--------------------------------------------------------------------
connection_info(doc) ->
["Test the API function ssl:connection_info/1"];
connection_info(suite) ->
@@ -213,7 +280,7 @@ connection_info(Config) when is_list(Config) ->
Version =
ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
- ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha,no_export}}},
+ ServerMsg = ClientMsg = {ok, {Version, {rsa,rc4_128,sha}}},
ssl_test_lib:check_result(Server, ServerMsg, Client, ClientMsg),
@@ -225,6 +292,49 @@ connection_info_result(Socket) ->
%%--------------------------------------------------------------------
+protocol_versions(doc) ->
+ ["Test to set a list of protocol versions in app environment."];
+
+protocol_versions(suite) ->
+ [];
+
+protocol_versions(Config) when is_list(Config) ->
+ basic_test(Config).
+
+empty_protocol_versions(doc) ->
+ ["Test to set an empty list of protocol versions in app environment."];
+
+empty_protocol_versions(suite) ->
+ [];
+
+empty_protocol_versions(Config) when is_list(Config) ->
+ basic_test(Config).
+
+
+basic_test(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, 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, ClientOpts}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+%%--------------------------------------------------------------------
+
controlling_process(doc) ->
["Test API function controlling_process/2"];
@@ -282,7 +392,7 @@ controlling_process_result(Socket, Pid, Msg) ->
ssl:send(Socket, Msg),
no_result_msg.
-
+%%--------------------------------------------------------------------
controller_dies(doc) ->
["Test that the socket is closed after controlling process dies"];
controller_dies(suite) -> [];
@@ -597,9 +707,12 @@ cipher_suites(suite) ->
[];
cipher_suites(Config) when is_list(Config) ->
- MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha,no_export},
+ MandatoryCipherSuite = {rsa,'3des_ede_cbc',sha},
[_|_] = Suites = ssl:cipher_suites(),
- true = lists:member(MandatoryCipherSuite, Suites).
+ true = lists:member(MandatoryCipherSuite, Suites),
+ Suites = ssl:cipher_suites(erlang),
+ [_|_] =ssl:cipher_suites(openssl).
+
%%--------------------------------------------------------------------
socket_options(doc) ->
["Test API function getopts/2 and setopts/2"];
@@ -634,9 +747,16 @@ socket_options(Config) when is_list(Config) ->
{options, ClientOpts}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
-
+
ssl_test_lib:close(Server),
- ssl_test_lib:close(Client).
+ ssl_test_lib:close(Client),
+
+ {ok, Listen} = ssl:listen(0, ServerOpts),
+ {ok,[{mode,list}]} = ssl:getopts(Listen, [mode]),
+ ok = ssl:setopts(Listen, [{mode, binary}]),
+ {ok,[{mode, binary}]} = ssl:getopts(Listen, [mode]),
+ {ok,[{recbuf, _}]} = ssl:getopts(Listen, [recbuf]),
+ ssl:close(Listen).
socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
%% Test get/set emulated opts
@@ -645,6 +765,8 @@ socket_options_result(Socket, Options, DefaultValues, NewOptions, NewValues) ->
{ok, NewValues} = ssl:getopts(Socket, NewOptions),
%% Test get/set inet opts
{ok,[{nodelay,false}]} = ssl:getopts(Socket, [nodelay]),
+ ssl:setopts(Socket, [{nodelay, true}]),
+ {ok,[{nodelay, true}]} = ssl:getopts(Socket, [nodelay]),
ok.
%%--------------------------------------------------------------------
@@ -665,7 +787,7 @@ misc_ssl_options(Config) when is_list(Config) ->
{password, []},
{reuse_session, fun(_,_,_,_) -> true end},
{debug, []},
- {cb_info, {gen_tcp, tcp, tcp_closed}}],
+ {cb_info, {gen_tcp, tcp, tcp_closed, tcp_error}}],
Server =
ssl_test_lib:start_server([{node, ServerNode}, {port, 0},
@@ -1271,9 +1393,9 @@ shutdown_error(Config) when is_list(Config) ->
ok = ssl:close(Listen),
{error, closed} = ssl:shutdown(Listen, read_write).
-%%--------------------------------------------------------------------
+%%-------------------------------------------------------------------
ciphers(doc) ->
- [""];
+ ["Test all ssl cipher suites in highest support ssl/tls version"];
ciphers(suite) ->
[];
@@ -1283,6 +1405,7 @@ ciphers(Config) when is_list(Config) ->
ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
Ciphers = ssl:cipher_suites(),
+ test_server:format("tls1 erlang cipher suites ~p~n", [Ciphers]),
Result = lists:map(fun(Cipher) ->
cipher(Cipher, Version, Config) end,
Ciphers),
@@ -1293,7 +1416,54 @@ ciphers(Config) when is_list(Config) ->
test_server:format("Cipher suite errors: ~p~n", [Error]),
test_server:fail(cipher_suite_failed_see_test_case_log)
end.
-
+
+ciphers_ssl3(doc) ->
+ ["Test all ssl cipher suites in ssl3"];
+
+ciphers_ssl3(suite) ->
+ [];
+
+ciphers_ssl3(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version({3,0}),
+
+ Ciphers = ssl:cipher_suites(),
+ test_server:format("ssl3 erlang cipher suites ~p~n", [Ciphers]),
+ 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.
+
+ciphers_openssl_names(doc) ->
+ ["Test all ssl cipher suites in highest support ssl/tls version"];
+
+ciphers_openssl_names(suite) ->
+ [];
+
+ciphers_openssl_names(Config) when is_list(Config) ->
+ Version =
+ ssl_record:protocol_version(ssl_record:highest_protocol_version([])),
+
+ Ciphers = ssl:cipher_suites(openssl),
+ test_server:format("tls1 openssl cipher suites ~p~n", [Ciphers]),
+ 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]),
@@ -1313,7 +1483,9 @@ cipher(CipherSuite, Version, Config) ->
[{ciphers,[CipherSuite]} |
ClientOpts]}]),
- ServerMsg = ClientMsg = {ok, {Version, CipherSuite}},
+ ErlangCipherSuite = erlang_cipher_suite(CipherSuite),
+
+ ServerMsg = ClientMsg = {ok, {Version, ErlangCipherSuite}},
Result = ssl_test_lib:wait_for_result(Server, ServerMsg,
Client, ClientMsg),
@@ -1332,9 +1504,14 @@ cipher(CipherSuite, Version, Config) ->
ok ->
[];
Error ->
- [{CipherSuite, Error}]
+ [{ErlangCipherSuite, Error}]
end.
+erlang_cipher_suite(Suite) when is_list(Suite)->
+ ssl_cipher:suite_definition(ssl_cipher:openssl_suite(Suite));
+erlang_cipher_suite(Suite) ->
+ Suite.
+
%%--------------------------------------------------------------------
reuse_session(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -1932,9 +2109,7 @@ server_require_peer_cert_fail(Config) when is_list(Config) ->
{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, {error, esslconnect}).
%%--------------------------------------------------------------------
@@ -2112,6 +2287,76 @@ server_renegotiate(Config) when is_list(Config) ->
ok.
%%--------------------------------------------------------------------
+client_renegotiate_reused_session(doc) ->
+ ["Test ssl:renegotiate/1 on client when the ssl session will be reused."];
+
+client_renegotiate_reused_session(suite) ->
+ [];
+
+client_renegotiate_reused_session(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_reuse_session, [Data]}},
+ {options, [{reuse_sessions, true} | 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_reused_session(doc) ->
+ ["Test ssl:renegotiate/1 on server when the ssl session will be reused."];
+
+server_renegotiate_reused_session(suite) ->
+ [];
+
+server_renegotiate_reused_session(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_reuse_session, [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, true} | 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"
@@ -2198,48 +2443,54 @@ extended_key_usage(suite) ->
[];
extended_key_usage(Config) when is_list(Config) ->
- ClientOpts = ?config(client_opts, Config),
- ServerOpts = ?config(server_opts, Config),
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
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),
-
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
{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)],
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ NewServerCertFile = filename:join(PrivDir, "server/new_cert.pem"),
+ {ok, [{cert, ServerDerCert, _}]} = public_key:pem_to_der(ServerCertFile),
+ {ok, ServerOTPCert} = public_key:pkix_decode_cert(ServerDerCert, otp),
+ ServerExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-serverAuth']},
+ ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
+ ServerExtensions = ServerOTPTbsCert#'OTPTBSCertificate'.extensions,
+ NewServerOTPTbsCert = ServerOTPTbsCert#'OTPTBSCertificate'{extensions =
+ [ServerExtKeyUsageExt |
+ ServerExtensions]},
+ NewServerDerCert = public_key:sign(NewServerOTPTbsCert, Key),
+ public_key:der_to_pem(NewServerCertFile, [{cert, NewServerDerCert, not_encrypted}]),
+ NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ ClientCertFile = proplists:get_value(certfile, ClientOpts),
+ NewClientCertFile = filename:join(PrivDir, "client/new_cert.pem"),
+ {ok, [{cert, ClientDerCert, _}]} = public_key:pem_to_der(ClientCertFile),
+ {ok, ClientOTPCert} = public_key:pkix_decode_cert(ClientDerCert, otp),
+ ClientExtKeyUsageExt = {'Extension', ?'id-ce-extKeyUsage', true, [?'id-kp-clientAuth']},
+ ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
+ ClientExtensions = ClientOTPTbsCert#'OTPTBSCertificate'.extensions,
+ NewClientOTPTbsCert = ClientOTPTbsCert#'OTPTBSCertificate'{extensions =
+ [ClientExtKeyUsageExt |
+ ClientExtensions]},
+ NewClientDerCert = public_key:sign(NewClientOTPTbsCert, Key),
+ public_key:der_to_pem(NewClientCertFile, [{cert, NewClientDerCert, not_encrypted}]),
+ NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
{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}]),
+ {options, [{verify, verify_peer} | 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}]),
+ {options, [{verify, verify_peer} | NewClientOpts]}]),
ssl_test_lib:check_result(Server, ok, Client, ok),
@@ -2282,6 +2533,245 @@ validate_extensions_fun(Config) when is_list(Config) ->
ssl_test_lib:close(Client).
%%--------------------------------------------------------------------
+no_authority_key_identifier(doc) ->
+ ["Test cert that does not have authorityKeyIdentifier extension"];
+
+no_authority_key_identifier(suite) ->
+ [];
+no_authority_key_identifier(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ CertFile = proplists:get_value(certfile, ServerOpts),
+ NewCertFile = filename:join(PrivDir, "server/new_cert.pem"),
+ {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(CertFile),
+ {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp),
+ OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
+ Extensions = OTPTbsCert#'OTPTBSCertificate'.extensions,
+ NewExtensions = delete_authority_key_extension(Extensions, []),
+ NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{extensions = NewExtensions},
+
+ test_server:format("Extensions ~p~n, NewExtensions: ~p~n", [Extensions, NewExtensions]),
+
+ NewDerCert = public_key:sign(NewOTPTbsCert, Key),
+ public_key:der_to_pem(NewCertFile, [{cert, NewDerCert, not_encrypted}]),
+ 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, [{verify, verify_peer} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, ok, Client, ok),
+
+ ssl_test_lib:close(Server),
+ ssl_test_lib:close(Client).
+
+delete_authority_key_extension([], Acc) ->
+ lists:reverse(Acc);
+delete_authority_key_extension([#'Extension'{extnID = ?'id-ce-authorityKeyIdentifier'} | Rest],
+ Acc) ->
+ delete_authority_key_extension(Rest, Acc);
+delete_authority_key_extension([Head | Rest], Acc) ->
+ delete_authority_key_extension(Rest, [Head | Acc]).
+
+%%--------------------------------------------------------------------
+
+invalid_signature_server(doc) ->
+ ["Test server with invalid signature"];
+
+invalid_signature_server(suite) ->
+ [];
+
+invalid_signature_server(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "server/key.pem"),
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ NewServerCertFile = filename:join(PrivDir, "server/invalid_cert.pem"),
+ {ok, [{cert, ServerDerCert, _}]} = public_key:pem_to_der(ServerCertFile),
+ {ok, ServerOTPCert} = public_key:pkix_decode_cert(ServerDerCert, otp),
+ ServerOTPTbsCert = ServerOTPCert#'OTPCertificate'.tbsCertificate,
+ NewServerDerCert = public_key:sign(ServerOTPTbsCert, Key),
+ public_key:der_to_pem(NewServerCertFile, [{cert, NewServerDerCert, not_encrypted}]),
+ NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, NewServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, "bad certificate"},
+ Client, {error,"bad certificate"}).
+
+%%--------------------------------------------------------------------
+
+invalid_signature_client(doc) ->
+ ["Test server with invalid signature"];
+
+invalid_signature_client(suite) ->
+ [];
+
+invalid_signature_client(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_verification_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "client/key.pem"),
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ ClientCertFile = proplists:get_value(certfile, ClientOpts),
+ NewClientCertFile = filename:join(PrivDir, "client/invalid_cert.pem"),
+ {ok, [{cert, ClientDerCert, _}]} = public_key:pem_to_der(ClientCertFile),
+ {ok, ClientOTPCert} = public_key:pkix_decode_cert(ClientDerCert, otp),
+ ClientOTPTbsCert = ClientOTPCert#'OTPCertificate'.tbsCertificate,
+ NewClientDerCert = public_key:sign(ClientOTPTbsCert, Key),
+ public_key:der_to_pem(NewClientCertFile, [{cert, NewClientDerCert, not_encrypted}]),
+ NewClientOpts = [{certfile, NewClientCertFile} | proplists:delete(certfile, ClientOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, [{verify, verify_peer} | ServerOpts]}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, NewClientOpts}]),
+
+ tcp_delivery_workaround(Server, {error, "bad certificate"},
+ Client, {error,"bad certificate"}).
+
+tcp_delivery_workaround(Server, ServMsg, Client, ClientMsg) ->
+ receive
+ {Server, ServerMsg} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ {Client, {error,closed}} ->
+ test_server:format("client got close");
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end;
+ {Client, ClientMsg} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end;
+ {Client, {error,closed}} ->
+ receive
+ {Server, ServerMsg} ->
+ ok;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end;
+ {Server, {error,closed}} ->
+ receive
+ {Client, ClientMsg} ->
+ ok;
+ {Client, {error,closed}} ->
+ test_server:format("client got close"),
+ ok;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end;
+ Unexpected ->
+ test_server:fail(Unexpected)
+ end.
+%%--------------------------------------------------------------------
+cert_expired(doc) ->
+ ["Test server with invalid signature"];
+
+cert_expired(suite) ->
+ [];
+
+cert_expired(Config) when is_list(Config) ->
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_verification_opts, Config),
+ PrivDir = ?config(priv_dir, Config),
+
+ KeyFile = filename:join(PrivDir, "otpCA/private/key.pem"),
+ {ok, [KeyInfo]} = public_key:pem_to_der(KeyFile),
+ {ok, Key} = public_key:decode_private_key(KeyInfo),
+
+ ServerCertFile = proplists:get_value(certfile, ServerOpts),
+ NewServerCertFile = filename:join(PrivDir, "server/expired_cert.pem"),
+ {ok, [{cert, DerCert, _}]} = public_key:pem_to_der(ServerCertFile),
+ {ok, OTPCert} = public_key:pkix_decode_cert(DerCert, otp),
+ OTPTbsCert = OTPCert#'OTPCertificate'.tbsCertificate,
+
+ {Year, Month, Day} = date(),
+ {Hours, Min, Sec} = time(),
+ NotBeforeStr = lists:flatten(io_lib:format("~p~s~s~s~s~sZ",[Year-2,
+ two_digits_str(Month),
+ two_digits_str(Day),
+ two_digits_str(Hours),
+ two_digits_str(Min),
+ two_digits_str(Sec)])),
+ NotAfterStr = lists:flatten(io_lib:format("~p~s~s~s~s~sZ",[Year-1,
+ two_digits_str(Month),
+ two_digits_str(Day),
+ two_digits_str(Hours),
+ two_digits_str(Min),
+ two_digits_str(Sec)])),
+ NewValidity = {'Validity', {generalTime, NotBeforeStr}, {generalTime, NotAfterStr}},
+
+ test_server:format("Validity: ~p ~n NewValidity: ~p ~n",
+ [OTPTbsCert#'OTPTBSCertificate'.validity, NewValidity]),
+
+ NewOTPTbsCert = OTPTbsCert#'OTPTBSCertificate'{validity = NewValidity},
+ NewServerDerCert = public_key:sign(NewOTPTbsCert, Key),
+ public_key:der_to_pem(NewServerCertFile, [{cert, NewServerDerCert, not_encrypted}]),
+ NewServerOpts = [{certfile, NewServerCertFile} | proplists:delete(certfile, ServerOpts)],
+
+ {ClientNode, ServerNode, Hostname} = ssl_test_lib:run_where(Config),
+
+ Server = ssl_test_lib:start_server_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, NewServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+ Client = ssl_test_lib:start_client_error([{node, ClientNode}, {port, Port},
+ {host, Hostname},
+ {from, self()},
+ {options, [{verify, verify_peer} | ClientOpts]}]),
+
+ ssl_test_lib:check_result(Server, {error, "certificate expired"},
+ Client, {error, "certificate expired"}).
+
+two_digits_str(N) when N < 10 ->
+ lists:flatten(io_lib:format("0~p", [N]));
+two_digits_str(N) ->
+ lists:flatten(io_lib:format("~p", [N])).
+
+%%--------------------------------------------------------------------
%%% Internal functions
%%--------------------------------------------------------------------
send_recv_result(Socket) ->
@@ -2314,14 +2804,14 @@ renegotiate(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.
+
+renegotiate_reuse_session(Socket, Data) ->
+ %% Make sure session is registerd
+ test_server:sleep(?SLEEP),
+ renegotiate(Socket, Data).
session_cache_process_list(doc) ->
["Test reuse of sessions (short handshake)"];
@@ -2340,128 +2830,34 @@ 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),
+ reuse_session(Config).
- 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
+init([Type]) ->
+ ets:new(ssl_test, [named_table, public, set]),
+ ets:insert(ssl_test, {type, Type}),
+ case Type of
list ->
spawn(fun() -> session_loop([]) end);
mnesia ->
mnesia:start(),
- {atomic,ok} = mnesia:create_table(sess_cache, [])
+ {atomic,ok} = mnesia:create_table(sess_cache, []),
+ sess_cache
end.
+session_cb() ->
+ [{type, Type}] = ets:lookup(ssl_test, type),
+ Type.
+
terminate(Cache) ->
- io:format("~p~n",[?LINE]),
case session_cb() of
list ->
Cache ! terminate;
mnesia ->
- {atomic,ok} = mnesia:delete_table(sess_cache, [])
+ catch {atomic,ok} =
+ mnesia:delete_table(sess_cache)
end.
-lookup(Cache, Key) ->
- io:format("~p~n",[?LINE]),
+lookup(Cache, Key) ->
case session_cb() of
list ->
Cache ! {self(), lookup, Key},
@@ -2471,13 +2867,14 @@ lookup(Cache, Key) ->
mnesia:read(sess_cache,
Key, read)
end) of
- {atomic, [Session]} -> Session;
- _ -> undefined
+ {atomic, [{sess_cache, Key, Value}]} ->
+ Value;
+ _ ->
+ undefined
end
- end.
+ end.
update(Cache, Key, Value) ->
- io:format("~p~n",[?LINE]),
case session_cb() of
list ->
Cache ! {update, Key, Value};
@@ -2485,12 +2882,11 @@ update(Cache, Key, Value) ->
{atomic, ok} =
mnesia:transaction(fun() ->
mnesia:write(sess_cache,
- Key, Value)
+ {sess_cache, Key, Value}, write)
end)
end.
delete(Cache, Key) ->
- io:format("~p~n",[?LINE]),
case session_cb() of
list ->
Cache ! {delete, Key};
@@ -2502,7 +2898,6 @@ delete(Cache, Key) ->
end.
foldl(Fun, Acc, Cache) ->
- io:format("~p~n",[?LINE]),
case session_cb() of
list ->
Cache ! {self(),foldl,Fun,Acc},
@@ -2516,15 +2911,17 @@ foldl(Fun, Acc, Cache) ->
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;
+ receive
+ {Cache, Res} ->
+ Res
+ end;
mnesia ->
Sel = fun() ->
mnesia:select(Cache,
- [{{{PartialKey,'$1'}, '$2'},
+ [{{sess_cache,{PartialKey,'$1'}, '$2'},
[],['$$']}])
end,
{atomic, Res} = mnesia:transaction(Sel),
@@ -2544,7 +2941,8 @@ session_loop(Sess) ->
end,
session_loop(Sess);
{update, Key, Value} ->
- session_loop([{Key,Value}|Sess]);
+ NewSess = [{Key,Value}| lists:keydelete(Key,1,Sess)],
+ session_loop(NewSess);
{delete, Key} ->
session_loop(lists:keydelete(Key,1,Sess));
{Pid,foldl,Fun,Acc} ->
@@ -2552,15 +2950,17 @@ session_loop(Sess) ->
Pid ! {self(), Res},
session_loop(Sess);
{Pid,select_session,PKey} ->
- Sel = fun({{Head, _},Session}, Acc) when Head =:= PKey ->
- [Session|Acc];
+ Sel = fun({{PKey0, Id},Session}, Acc) when PKey == PKey0 ->
+ [[Id, Session]|Acc];
(_,Acc) ->
Acc
- end,
- Pid ! {self(), lists:foldl(Sel, [], Sess)},
+ end,
+ Sessions = lists:foldl(Sel, [], Sess),
+ Pid ! {self(), Sessions},
session_loop(Sess)
end.
+
erlang_ssl_receive(Socket, Data) ->
receive
{ssl, Socket, Data} ->
diff --git a/lib/ssl/test/ssl_to_openssl_SUITE.erl b/lib/ssl/test/ssl_to_openssl_SUITE.erl
index 186bf52ff6..1c18f10038 100644
--- a/lib/ssl/test/ssl_to_openssl_SUITE.erl
+++ b/lib/ssl/test/ssl_to_openssl_SUITE.erl
@@ -33,6 +33,7 @@
-define(OPENSSL_RENEGOTIATE, "r\n").
-define(OPENSSL_QUIT, "Q\n").
-define(OPENSSL_GARBAGE, "P\n").
+-define(EXPIRE, 10).
%% Test server callback functions
%%--------------------------------------------------------------------
@@ -81,11 +82,29 @@ end_per_suite(_Config) ->
%% variable, but should NOT alter/remove any existing entries.
%% Description: Initialization before each test case
%%--------------------------------------------------------------------
-init_per_testcase(_TestCase, Config0) ->
+init_per_testcase(expired_session, 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 = ssl_test_lib:timetrap(?TIMEOUT),
- [{watchdog, Dog} | Config].
+ special_init(TestCase, [{watchdog, Dog} | Config]).
+special_init(TestCase, Config)
+ when TestCase == erlang_client_openssl_server_renegotiate;
+ TestCase == erlang_client_openssl_server_no_wrap_sequence_number;
+ TestCase == erlang_server_openssl_client_no_wrap_sequence_number ->
+ check_sane_openssl_renegotaite(Config);
+
+special_init(_, Config) ->
+ Config.
+
%%--------------------------------------------------------------------
%% Function: end_per_testcase(TestCase, Config) -> _
%% Case - atom()
@@ -94,14 +113,20 @@ init_per_testcase(_TestCase, Config0) ->
%% A list of key/value pairs, holding the test case configuration.
%% Description: Cleanup after each test case
%%--------------------------------------------------------------------
-end_per_testcase(_TestCase, Config) ->
+end_per_testcase(reuse_session_expired, Config) ->
+ application:unset_env(ssl, session_lifetime),
+ end_per_testcase(default_action, Config);
+
+end_per_testcase(default_action, Config) ->
Dog = ?config(watchdog, Config),
case Dog of
undefined ->
ok;
_ ->
test_server:timetrap_cancel(Dog)
- end.
+ end;
+end_per_testcase(_, Config) ->
+ end_per_testcase(default_action, Config).
%%--------------------------------------------------------------------
%% Function: all(Clause) -> TestCases
@@ -133,7 +158,9 @@ all(suite) ->
tls1_erlang_server_openssl_client_client_cert,
tls1_erlang_server_erlang_client_client_cert,
ciphers,
- erlang_client_bad_openssl_server
+ erlang_client_bad_openssl_server,
+ expired_session,
+ ssl2_erlang_server_openssl_client
].
%% Test cases starts here.
@@ -297,12 +324,8 @@ erlang_client_openssl_server_renegotiate(Config) when is_list(Config) ->
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),
-
+ ssl_test_lib:check_result(Client, ok),
+
%% Clean close down! Server needs to be closed first !!
close_port(OpensslPort),
@@ -350,11 +373,7 @@ erlang_client_openssl_server_no_wrap_sequence_number(Config) when is_list(Config
{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),
+ ssl_test_lib:check_result(Client, ok),
%% Clean close down! Server needs to be closed first !!
close_port(OpensslPort),
@@ -990,6 +1009,100 @@ erlang_client_bad_openssl_server(Config) when is_list(Config) ->
close_port(OpensslPort),
process_flag(trap_exit, false),
ok.
+
+%%--------------------------------------------------------------------
+
+expired_session(doc) ->
+ ["Test our ssl client handling of expired sessions. Will make"
+ "better code coverage of the ssl_manager module"];
+
+expired_session(suite) ->
+ [];
+
+expired_session(Config) when is_list(Config) ->
+ process_flag(trap_exit, true),
+ ClientOpts = ?config(client_opts, Config),
+ ServerOpts = ?config(server_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(),
+
+ Client0 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ ssl_test_lib:close(Client0),
+
+ %% Make sure session is registered
+ test_server:sleep(?SLEEP),
+
+ Client1 =
+ ssl_test_lib:start_client([{node, ClientNode},
+ {port, Port}, {host, Hostname},
+ {mfa, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ ssl_test_lib:close(Client1),
+ %% 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, {ssl_test_lib, no_result, []}},
+ {from, self()}, {options, ClientOpts}]),
+
+ close_port(OpensslPort),
+ ssl_test_lib:close(Client2),
+ process_flag(trap_exit, false).
+
+%%--------------------------------------------------------------------
+ssl2_erlang_server_openssl_client(doc) ->
+ ["Test that ssl v2 clients are rejected"];
+ssl2_erlang_server_openssl_client(suite) ->
+ [];
+ssl2_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_error([{node, ServerNode}, {port, 0},
+ {from, self()},
+ {options, ServerOpts}]),
+ Port = ssl_test_lib:inet_port(Server),
+
+ Cmd = "openssl s_client -port " ++ integer_to_list(Port) ++
+ " -host localhost -ssl2 -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, {error,"protocol version"}),
+
+ ssl_test_lib:close(Server),
+
+ close_port(OpenSslPort),
+ process_flag(trap_exit, false),
+ ok.
+
%%--------------------------------------------------------------------
erlang_ssl_receive(Socket, Data) ->
@@ -1029,8 +1142,7 @@ delayed_send(Socket, [ErlData, OpenSslData]) ->
erlang_ssl_receive(Socket, OpenSslData).
close_port(Port) ->
- port_command(Port, ?OPENSSL_QUIT),
- %%catch port_command(Port, "quit\n"),
+ catch port_command(Port, ?OPENSSL_QUIT),
close_loop(Port, 500, false).
close_loop(Port, Time, SentClose) ->
@@ -1080,3 +1192,10 @@ wait_for_openssl_server() ->
test_server:sleep(?SLEEP)
end.
+check_sane_openssl_renegotaite(Config) ->
+ case os:cmd("openssl version") of
+ "OpenSSL 0.9.8l" ++ _ ->
+ {skip, "Known renegotiation bug in OppenSSL"};
+ _ ->
+ Config
+ end.
diff --git a/lib/ssl/vsn.mk b/lib/ssl/vsn.mk
index 6db1a4b5c2..e3db7008e3 100644
--- a/lib/ssl/vsn.mk
+++ b/lib/ssl/vsn.mk
@@ -19,7 +19,9 @@
SSL_VSN = 3.11.1
-TICKETS = OTP-8588
+TICKETS = OTP-8588 \
+ OTP-8568 \
+ OTP-7049
#TICKETS_3.11 = OTP-8517 \
# OTP-7046 \
diff --git a/lib/stdlib/doc/src/Makefile b/lib/stdlib/doc/src/Makefile
index 13b9b2ff18..b558697d63 100644
--- a/lib/stdlib/doc/src/Makefile
+++ b/lib/stdlib/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
@@ -40,6 +40,7 @@ XML_REF3_FILES = \
array.xml \
base64.xml \
beam_lib.xml \
+ binary.xml \
c.xml \
calendar.xml \
dets.xml \
diff --git a/lib/stdlib/doc/src/beam_lib.xml b/lib/stdlib/doc/src/beam_lib.xml
index b9286f1402..27308e02f3 100644
--- a/lib/stdlib/doc/src/beam_lib.xml
+++ b/lib/stdlib/doc/src/beam_lib.xml
@@ -347,9 +347,10 @@ chunkref() = chunkname() | chunkid()</code>
</type>
<desc>
<p>Compares the contents of two BEAM files. If the module names
- are the same, and the chunks with the identifiers
- <c>"Code"</c>, <c>"ExpT"</c>, <c>"ImpT"</c>, <c>"StrT"</c>,
- and <c>"Atom"</c> have the same contents in both files,
+ are the same, and all chunks except for the <c>"CInf"</c> chunk
+ (the chunk containing the compilation information which is
+ returned by <c>Module:module_info(compile)</c>)
+ have the same contents in both files,
<c>ok</c> is returned. Otherwise an error message is returned.</p>
</desc>
</func>
diff --git a/lib/stdlib/doc/src/binary.xml b/lib/stdlib/doc/src/binary.xml
new file mode 100644
index 0000000000..c5eb81a86a
--- /dev/null
+++ b/lib/stdlib/doc/src/binary.xml
@@ -0,0 +1,729 @@
+<?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 on line at http://www.erlang.org/.
+
+ Software distributed under the License is distributed on an "AS IS"
+ 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>binary</title>
+ <prepared>Patrik Nyblom</prepared>
+ <responsible>Kenneth Lundin</responsible>
+ <docno>1</docno>
+ <approved></approved>
+ <checked></checked>
+ <date>2010-05-05</date>
+ <rev>A</rev>
+ <file>binary.xml</file>
+ </header>
+ <module>binary</module>
+ <modulesummary>Library for handling binary data</modulesummary>
+ <description>
+
+ <p>This module contains functions for manipulating byte-oriented
+ binaries. Although the majority of functions could be implemented
+ using bit-syntax, the functions in this library are highly
+ optimized and are expected to either execute faster or consume
+ less memory (or both) than a counterpart written in pure Erlang.</p>
+
+ <p>The module is implemented according to the EEP (Erlang Enhancement Proposal) 31.</p>
+
+ <note>
+ <p>
+ The library handles byte-oriented data. Bitstrings that are not
+ binaries (does not contain whole octets of bits) will result in a <c>badarg</c>
+ exception being thrown from any of the functions in this
+ module.
+ </p>
+ </note>
+
+
+ </description>
+ <section>
+ <title>DATA TYPES</title>
+ <code type="none">
+ cp()
+ - Opaque data-type representing a compiled search-pattern. Guaranteed to be a tuple()
+ to allow programs to distinguish it from non precompiled search patterns.
+ </code>
+ <code type="none">
+ part() = {Start,Length}
+ Start = int()
+ Length = int()
+ - A representaion of a part (or range) in a binary. Start is a
+ zero-based offset into a binary() and Length is the length of
+ that part. As input to functions in this module, a reverse
+ part specification is allowed, constructed with a negative
+ Length, so that the part of the binary begins at Start +
+ Length and is -Length long. This is useful for referencing the
+ last N bytes of a binary as {size(Binary), -N}. The functions
+ in this module always return part()'s with positive Length.
+ </code>
+ </section>
+ <funcs>
+ <func>
+ <name>at(Subject, Pos) -> int()</name>
+ <fsummary>Returns the byte at a specific position in a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pos = int() >= 0</v>
+ </type>
+ <desc>
+
+ <p>Returns the byte at position <c>Pos</c> (zero-based) in the binary
+ <c>Subject</c> as an integer. If <c>Pos</c> &gt;= <c>byte_size(Subject)</c>,
+ a <c>badarg</c>
+ exception is raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>bin_to_list(Subject) -> list()</name>
+ <fsummary>Convert a binary to a list of integers</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ </type>
+ <desc>
+ <p>The same as <c>bin_to_list(Subject,{0,byte_size(Subject)})</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>bin_to_list(Subject, PosLen) -> list()</name>
+ <fsummary>Convert a binary to a list of integers</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>PosLen = part()</v>
+ </type>
+ <desc>
+
+ <p>Converts <c>Subject</c> to a list of <c>int()</c>s, each representing
+ the value of one byte. The <c>part()</c> denotes which part of the
+ <c>binary()</c> to convert. Example:</p>
+
+<code>
+1> binary:bin_to_list(&lt;&lt;"erlang"&gt;&gt;,{1,3}).
+"rla"
+%% or [114,108,97] in list notation.
+</code>
+ <p>If <c>PosLen</c> in any way references outside the binary, a <c>badarg</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>bin_to_list(Subject, Pos, Len) -> list()</name>
+ <fsummary>Convert a binary to a list of integers</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pos = int()</v>
+ <v>Len = int()</v>
+ </type>
+ <desc>
+ <p>The same as<c> bin_to_list(Subject,{Pos,Len})</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>compile_pattern(Pattern) -> cp()</name>
+ <fsummary>Pre-compiles a binary search pattern</fsummary>
+ <type>
+ <v>Pattern = binary() | [ binary() ]</v>
+ </type>
+ <desc>
+
+ <p>Builds an internal structure representing a compilation of a
+ search-pattern, later to be used in the <seealso marker="#match-3">match/3</seealso>,
+ <seealso marker="#matches-3">matches/3</seealso>,
+ <seealso marker="#split-3">split/3</seealso> or
+ <seealso marker="#replace-4">replace/4</seealso>
+ functions. The <c>cp()</c> returned is guaranteed to be a
+ <c>tuple()</c> to allow programs to distinguish it from non
+ pre-compiled search patterns</p>
+
+ <p>When a list of binaries is given, it denotes a set of
+ alternative binaries to search for. I.e if
+ <c>[&lt;&lt;"functional"&gt;&gt;,&lt;&lt;"programming"&gt;&gt;]</c>
+ is given as <c>Pattern</c>, this
+ means "either <c>&lt;&lt;"functional"&gt;&gt;</c> or
+ <c>&lt;&lt;"programming"&gt;&gt;</c>". The pattern is a set of
+ alternatives; when only a single binary is given, the set has
+ only one element. The order of alternatives in a pattern is not significant.</p>
+
+ <p>The list of binaries used for search alternatives shall be flat and proper.</p>
+
+ <p>If <c>Pattern</c> is not a binary or a flat proper list of binaries with length &gt; 0,
+ a <c>badarg</c> exception will be raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>copy(Subject) -> binary()</name>
+ <fsummary>Creates a duplicate of a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ </type>
+ <desc>
+ <p>The same as <c>copy(Subject, 1)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>copy(Subject,N) -> binary()</name>
+ <fsummary>Duplicates a binary N times and creates a new</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>N = int() >= 0</v>
+ </type>
+ <desc>
+ <p>Creates a binary with the content of <c>Subject</c> duplicated <c>N</c> times.</p>
+
+ <p>This function will always create a new binary, even if <c>N =
+ 1</c>. By using <c>copy/1</c> on a binary referencing a larger binary, one
+ might free up the larger binary for garbage collection.</p>
+
+ <note>
+ <p>By deliberately copying a single binary to avoid referencing
+ a larger binary, one might, instead of freeing up the larger
+ binary for later garbage collection, create much more binary
+ data than needed. Sharing binary data is usually good. Only in
+ special cases, when small parts reference large binaries and the
+ large binaries are no longer used in any process, deliberate
+ copying might be a good idea.</p> </note>
+
+ <p>If <c>N</c> &lt; <c>0</c>, a <c>badarg</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>decode_unsigned(Subject) -> Unsigned</name>
+ <fsummary>Decode a whole binary into an integer of arbitrary size</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Unsigned = int() >= 0</v>
+ </type>
+ <desc>
+ <p>The same as <c>decode_unsigned(Subject,big)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>decode_unsigned(Subject, Endianess) -> Unsigned</name>
+ <fsummary>Decode a whole binary into an integer of arbitrary size</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Endianess = big | little</v>
+ <v>Unsigned = int() >= 0</v>
+ </type>
+ <desc>
+
+ <p>Converts the binary digit representation, in big or little
+ endian, of a positive integer in <c>Subject</c> to an Erlang <c>int()</c>.</p>
+
+ <p>Example:</p>
+
+ <code>
+1> binary:decode_unsigned(&lt;&lt;169,138,199&gt;&gt;,big).
+11111111
+ </code>
+ </desc>
+ </func>
+ <func>
+ <name>encode_unsigned(Unsigned) -> binary()</name>
+ <fsummary>Encodes an unsigned integer into the minimal binary</fsummary>
+ <type>
+ <v>Unsigned = int() >= 0</v>
+ </type>
+ <desc>
+ <p>The same as <c>encode_unsigned(Unsigned,big)</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>encode_unsigned(Unsigned,Endianess) -> binary()</name>
+ <fsummary>Encodes an unsigned integer into the minimal binary</fsummary>
+ <type>
+ <v>Unsigned = int() >= 0</v>
+ <v>Endianess = big | little</v>
+ </type>
+ <desc>
+
+ <p>Converts a positive integer to the smallest possible
+ representation in a binary digit representation, either big
+ or little endian.</p>
+
+ <p>Example:</p>
+
+ <code>
+1> binary:encode_unsigned(11111111,big).
+&lt;&lt;169,138,199&gt;&gt;
+ </code>
+ </desc>
+ </func>
+ <func>
+ <name>first(Subject) -> int()</name>
+ <fsummary>Returns the first byte of a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ </type>
+ <desc>
+
+ <p>Returns the first byte of the binary <c>Subject</c> as an integer. If the
+ size of <c>Subject</c> is zero, a <c>badarg</c> exception is raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>last(Subject) -> int()</name>
+ <fsummary>Returns the last byte of a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ </type>
+ <desc>
+
+ <p>Returns the last byte of the binary <c>Subject</c> as an integer. If the
+ size of <c>Subject</c> is zero, a <c>badarg</c> exception is raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>list_to_bin(ByteList) -> binary()</name>
+ <fsummary>Convert a list of integers and binaries to a binary</fsummary>
+ <type>
+ <v>ByteList = iodata() (see module erlang)</v>
+ </type>
+ <desc>
+ <p>Works exactly as <c>erlang:list_to_binary/1</c>, added for completeness.</p>
+ </desc>
+ </func>
+ <func>
+ <name>longest_common_prefix(Binaries) -> int()</name>
+ <fsummary>Returns length of longest common prefix for a set of binaries</fsummary>
+ <type>
+ <v>Binaries = [ binary() ]</v>
+ </type>
+ <desc>
+
+ <p>Returns the length of the longest common prefix of the
+ binaries in the list <c>Binaries</c>. Example:</p>
+
+<code>
+1> binary:longest_common_prefix([&lt;&lt;"erlang"&gt;&gt;,&lt;&lt;"ergonomy"&gt;&gt;]).
+2
+2> binary:longest_common_prefix([&lt;&lt;"erlang"&gt;&gt;,&lt;&lt;"perl"&gt;&gt;]).
+0
+</code>
+
+ <p>If <c>Binaries</c> is not a flat list of binaries, a <c>badarg</c> exception is raised.</p>
+ </desc>
+ </func>
+ <func>
+ <name>longest_common_suffix(Binaries) -> int()</name>
+ <fsummary>Returns length of longest common suffix for a set of binaries</fsummary>
+ <type>
+ <v>Binaries = [ binary() ]</v>
+ </type>
+ <desc>
+
+ <p>Returns the length of the longest common suffix of the
+ binaries in the list <c>Binaries</c>. Example:</p>
+
+<code>
+1> binary:longest_common_suffix([&lt;&lt;"erlang"&gt;&gt;,&lt;&lt;"fang"&gt;&gt;]).
+3
+2> binary:longest_common_suffix([&lt;&lt;"erlang"&gt;&gt;,&lt;&lt;"perl"&gt;&gt;]).
+0
+</code>
+
+ <p>If <c>Binaries</c> is not a flat list of binaries, a <c>badarg</c> exception is raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>match(Subject, Pattern) -> Found | <c>nomatch</c></name>
+ <fsummary>Searches for the first match of a pattern in a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Found = part()</v>
+ </type>
+ <desc>
+ <p>The same as <c>match(Subject, Pattern, [])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>match(Subject,Pattern,Options) -> Found | <c>nomatch</c></name>
+ <fsummary>Searches for the first match of a pattern in a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Found = part()</v>
+ <v>Options = [ Option ]</v>
+ <v>Option = {scope, part()}</v>
+ </type>
+ <desc>
+
+ <p>Searches for the first occurrence of <c>Pattern</c> in <c>Subject</c> and
+ returns the position and length.</p>
+
+ <p>The function will return <c>{Pos,Length}</c> for the binary
+ in <c>Pattern</c> starting at the lowest position in
+ <c>Subject</c>, Example:</p>
+
+<code>
+1> binary:match(&lt;&lt;"abcde"&gt;&gt;, [&lt;&lt;"bcde"&gt;&gt;,&lt;&lt;"cd"&gt;&gt;],[]).
+{1,4}
+</code>
+
+ <p>Even though <c>&lt;&lt;"cd"&gt;&gt;</c> ends before
+ <c>&lt;&lt;"bcde"&gt;&gt;</c>, <c>&lt;&lt;"bcde"&gt;&gt;</c>
+ begins first and is therefore the first match. If two
+ overlapping matches begin at the same position, the longest is
+ returned.</p>
+
+ <p>Summary of the options:</p>
+
+ <taglist>
+ <tag>{scope, {Start, Length}}</tag>
+ <item><p>Only the given part is searched. Return values still have
+ offsets from the beginning of <c>Subject</c>. A negative <c>Length</c> is
+ allowed as described in the <c>TYPES</c> section of this manual.</p></item>
+ </taglist>
+
+ <p>If none of the strings in
+ <c>Pattern</c> is found, the atom <c>nomatch</c> is returned.</p>
+
+ <p>For a description of <c>Pattern</c>, see
+ <seealso marker="#compile_pattern-1">compile_pattern/1</seealso>.</p>
+
+ <p>If <c>{scope, {Start,Length}}</c> is given in the options
+ such that <c>Start</c> is larger than the size of
+ <c>Subject</c>, <c>Start + Length</c> is less than zero or
+ <c>Start + Length</c> is larger than the size of
+ <c>Subject</c>, a <c>badarg</c> exception is raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>matches(Subject, Pattern) -> Found</name>
+ <fsummary>Searches for all matches of a pattern in a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Found = [ part() ] | []</v>
+ </type>
+ <desc>
+ <p>The same as <c>matches(Subject, Pattern, [])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>matches(Subject,Pattern,Options) -> Found</name>
+ <fsummary>Searches for all matches of a pattern in a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Found = [ part() ] | []</v>
+ <v>Options = [ Option ]</v>
+ <v>Option = {scope, part()}</v>
+ </type>
+ <desc>
+
+ <p>Works like match, but the <c>Subject</c> is searched until
+ exhausted and a list of all non-overlapping parts matching
+ <c>Pattern</c> is returned (in order). </p>
+
+ <p>The first and longest match is preferred to a shorter,
+ which is illustrated by the following example:</p>
+
+<code>
+1> binary:matches(&lt;&lt;"abcde"&gt;&gt;,
+ [&lt;&lt;"bcde"&gt;&gt;,&lt;&lt;"bc"&gt;&gt;>,&lt;&lt;"de"&gt;&gt;],[]).
+[{1,4}]
+</code>
+
+ <p>The result shows that &lt;&lt;bcde"&gt;&gt; is selected instead of the
+ shorter match &lt;&lt;"bc"&gt;&gt; (which would have given raise to one
+ more match,&lt;&lt;"de"&gt;&gt;). This corresponds to the behavior of posix
+ regular expressions (and programs like awk), but is not
+ consistent with alternative matches in re (and Perl), where
+ instead lexical ordering in the search pattern selects which
+ string matches.</p>
+
+ <p>If none of the strings in pattern is found, an empty list is returned.</p>
+
+ <p>For a description of <c>Pattern</c>, see <seealso marker="#compile_pattern-1">compile_pattern/1</seealso> and for a
+ description of available options, see <seealso marker="#match-3">match/3</seealso>.</p>
+
+ <p>If <c>{scope, {Start,Length}}</c> is given in the options such that
+ <c>Start</c> is larger than the size of <c>Subject</c>, <c>Start + Length</c> is
+ less than zero or <c>Start + Length</c> is larger than the size of
+ <c>Subject</c>, a <c>badarg</c> exception is raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>part(Subject, PosLen) -> binary()</name>
+ <fsummary>Extracts a part of a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>PosLen = part()</v>
+ </type>
+ <desc>
+
+ <p>Extracts the part of the binary <c>Subject</c> described by <c>PosLen</c>.</p>
+
+ <p>Negative length can be used to extract bytes at the end of a binary:</p>
+
+<code>
+1> Bin = &lt;&lt;1,2,3,4,5,6,7,8,9,10&gt;&gt;.
+2> binary:part(Bin,{byte_size(Bin), -5)).
+&lt;&lt;6,7,8,9,10&gt;&gt;
+</code>
+
+ <note>
+ <p><seealso marker="#part-2">part/2</seealso>and <seealso
+ marker="#part-3">part/3</seealso> are also available in the
+ <c>erlang</c> module under the names <c>binary_part/2</c> and
+ <c>binary_part/3</c>. Those BIFs are allowed in guard tests.</p>
+ </note>
+
+ <p>If <c>PosLen</c> in any way references outside the binary, a <c>badarg</c> exception
+ is raised.</p>
+
+ </desc>
+ </func>
+ <func>
+ <name>part(Subject, Pos, Len) -> binary()</name>
+ <fsummary>Extracts a part of a binary</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pos = int()</v>
+ <v>Len = int()</v>
+ </type>
+ <desc>
+ <p>The same as <c>part(Subject, {Pos, Len})</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>referenced_byte_size(binary()) -> int()</name>
+ <fsummary>Determines the size of the actual binary pointed out by a sub-binary</fsummary>
+ <desc>
+
+ <p>If a binary references a larger binary (often described as
+ being a sub-binary), it can be useful to get the size of the
+ actual referenced binary. This function can be used in a program
+ to trigger the use of <c>copy/1</c>. By copying a binary, one might
+ dereference the original, possibly large, binary which a smaller
+ binary is a reference to.</p>
+
+ <p>Example:</p>
+
+ <code>
+store(Binary, GBSet) ->
+ NewBin =
+ case binary:referenced_byte_size(Binary) of
+ Large when Large > 2 * byte_size(Binary) ->
+ binary:copy(Binary);
+ _ ->
+ Binary
+ end,
+ gb_sets:insert(NewBin,GBSet).
+ </code>
+
+ <p>In this example, we chose to copy the binary content before
+ inserting it in the <c>gb_set()</c> if it references a binary more than
+ twice the size of the data we're going to keep. Of course
+ different rules for when copying will apply to different
+ programs.</p>
+
+ <p>Binary sharing will occur whenever binaries are taken apart,
+ this is the fundamental reason why binaries are fast,
+ decomposition can always be done with O(1) complexity. In rare
+ circumstances this data sharing is however undesirable, why this
+ function together with <c>copy/1</c> might be useful when optimizing
+ for memory use.</p>
+
+ <p>Example of binary sharing:</p>
+
+ <code>
+1> A = binary:copy(&lt;&lt;1&gt;&gt;,100).
+&lt;&lt;1,1,1,1,1 ...
+2> byte_size(A).
+100
+3> binary:referenced_byte_size(A)
+100
+4> &lt;&lt;_:10/binary,B:10/binary,_/binary&gt;&gt; = A.
+&lt;&lt;1,1,1,1,1 ...
+5> byte_size(B).
+10
+6> binary:referenced_byte_size(B)
+100
+ </code>
+
+ <note>
+ <p>Binary data is shared among processes. If another process
+ still references the larger binary, copying the part this
+ process uses only consumes more memory and will not free up the
+ larger binary for garbage collection. Use this kind of intrusive
+ functions with extreme care, and only if a real problem is
+ detected.</p>
+ </note>
+
+ </desc>
+ </func>
+ <func>
+ <name>replace(Subject,Pattern,Replacement) -> Result</name>
+ <fsummary>Replaces bytes in a binary according to a pattern</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Replacement = binary()</v>
+ <v>Result = binary()</v>
+ </type>
+ <desc>
+ <p>The same as <c>replace(Subject,Pattern,Replacement,[])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>replace(Subject,Pattern,Replacement,Options) -> Result</name>
+ <fsummary>Replaces bytes in a binary according to a pattern</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Replacement = binary()</v>
+ <v>Result = binary()</v>
+ <v>Options = [ Option ]</v>
+ <v>Option = global | {scope, part()} | {insert_replaced, InsPos}</v>
+ <v>InsPos = OnePos | [ OnePos ]</v>
+ <v>OnePos = int() =&lt; byte_size(Replacement)</v>
+ </type>
+ <desc>
+
+ <p>Constructs a new binary by replacing the parts in
+ <c>Subject</c> matching <c>Pattern</c> with the content of
+ <c>Replacement</c>.</p>
+
+ <p>If the matching sub-part of <c>Subject</c> giving raise to the
+ replacement is to be inserted in the result, the option
+ <c>{insert_replaced, InsPos}</c> will insert the matching part into
+ <c>Replacement</c> at the given position (or positions) before actually
+ inserting <c>Replacement</c> into the <c>Subject</c>. Example:</p>
+
+<code>
+1> binary:replace(&lt;&lt;"abcde"&gt;&gt;,&lt;&lt;"b"&gt;&gt;,&lt;&lt;"[]"&gt;&gt;,[{insert_replaced,1}]).
+&lt;&lt;"a[b]cde"&gt;&gt;
+2> binary:replace(&lt;&lt;"abcde"&gt;&gt;,[&lt;&lt;"b"&gt;&gt;,&lt;&lt;"d"&gt;&gt;],&lt;&lt;"[]"&gt;&gt;,
+ [global,{insert_replaced,1}]).
+&lt;&lt;"a[b]c[d]e"&gt;&gt;
+3> binary:replace(&lt;&lt;"abcde"&gt;&gt;,[&lt;&lt;"b"&gt;&gt;,&lt;&lt;"d"&gt;&gt;],&lt;&lt;"[]"&gt;&gt;,
+ [global,{insert_replaced,[1,1]}]).
+&lt;&lt;"a[bb]c[dd]e"&gt;&gt;
+4> binary:replace(&lt;&lt;"abcde"&gt;&gt;,[&lt;&lt;"b"&gt;&gt;,&lt;&lt;"d"&gt;&gt;],&lt;&lt;"[-]"&gt;&gt;,
+ [global,{insert_replaced,[1,2]}]).
+&lt;&lt;"a[b-b]c[d-d]e"&gt;&gt;
+</code>
+
+ <p>If any position given in <c>InsPos</c> is greater than the size of the replacement binary, a <c>badarg</c> exception is raised.</p>
+
+ <p>The options <c>global</c> and <c>{scope, part()}</c> work as for <seealso marker="#split-3">split/3</seealso>. The return type is always a <c>binary()</c>.</p>
+
+ <p>For a description of <c>Pattern</c>, see <seealso marker="#compile_pattern-1">compile_pattern/1</seealso>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>split(Subject,Pattern) -> Parts</name>
+ <fsummary>Splits a binary according to a pattern</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Parts = [ binary() ]</v>
+ </type>
+ <desc>
+ <p>The same as <c>split(Subject, Pattern, [])</c>.</p>
+ </desc>
+ </func>
+ <func>
+ <name>split(Subject,Pattern,Options) -> Parts</name>
+ <fsummary>Splits a binary according to a pattern</fsummary>
+ <type>
+ <v>Subject = binary()</v>
+ <v>Pattern = binary() | [ binary() ] | cp()</v>
+ <v>Parts = [ binary() ]</v>
+ <v>Options = [ Option ]</v>
+ <v>Option = {scope, part()} | trim | global</v>
+ </type>
+ <desc>
+
+ <p>Splits Binary into a list of binaries based on Pattern. If
+ the option global is not given, only the first occurrence of
+ Pattern in Subject will give rise to a split.</p>
+
+ <p>The parts of Pattern actually found in Subject are not included in the result.</p>
+
+ <p>Example:</p>
+
+<code>
+1> binary:split(&lt;&lt;1,255,4,0,0,0,2,3&gt;&gt;, [&lt;&lt;0,0,0&gt;&gt;,&lt;&lt;2&gt;&gt;],[]).
+[&lt;&lt;1,255,4&gt;&gt;, &lt;&lt;2,3&gt;&gt;]
+2> binary:split(&lt;&lt;0,1,0,0,4,255,255,9&gt;&gt;, [&lt;&lt;0,0&gt;&gt;, &lt;&lt;255,255&gt;&gt;],[global]).
+[&lt;&lt;0,1&gt;&gt;,&lt;&lt;4&gt;&gt;,&lt;&lt;9&gt;&gt;]
+</code>
+
+ <p>Summary of options:</p>
+ <taglist>
+
+ <tag>{scope, part()}</tag>
+
+ <item><p>Works as in <seealso marker="#match-3">match/3</seealso> and
+ <seealso marker="#matches-3">matches/3</seealso>. Note that
+ this only defines the scope of the search for matching strings,
+ it does not cut the binary before splitting. The bytes before
+ and after the scope will be kept in the result. See example
+ below.</p></item>
+
+ <tag>trim</tag>
+
+ <item><p>Removes trailing empty parts of the result (as does trim in <c>re:split/3</c>)</p></item>
+
+ <tag>global</tag>
+
+ <item><p>Repeats the split until the <c>Subject</c> is
+ exhausted. Conceptually the global option makes split work on
+ the positions returned by <seealso marker="#matches-3">matches/3</seealso>,
+ while it normally
+ works on the position returned by
+ <seealso marker="#match-3">match/3</seealso>.</p></item>
+
+ </taglist>
+
+ <p>Example of the difference between a scope and taking the
+ binary apart before splitting:</p>
+
+<code>
+1> binary:split(&lt;&lt;"banana"&gt;&gt;,[&lt;&lt;"a"&gt;&gt;],[{scope,{2,3}}]).
+[&lt;&lt;"ban"&gt;&gt;,&lt;&lt;"na"&gt;&gt;]
+2> binary:split(binary:part(&lt;&lt;"banana"&gt;&gt;,{2,3}),[&lt;&lt;"a"&gt;&gt;],[]).
+[&lt;&lt;"n"&gt;&gt;,&lt;&lt;"n"&gt;&gt;]
+</code>
+
+ <p>The return type is always a list of binaries that are all
+ referencing <c>Subject</c>. This means that the data in <c>Subject</c> is not
+ actually copied to new binaries and that <c>Subject</c> cannot be
+ garbage collected until the results of the split are no longer
+ referenced.</p>
+
+ <p>For a description of <c>Pattern</c>, see <seealso marker="#compile_pattern-1">compile_pattern/1</seealso>.</p>
+
+ </desc>
+ </func>
+ </funcs>
+</erlref>
diff --git a/lib/stdlib/doc/src/gen_event.xml b/lib/stdlib/doc/src/gen_event.xml
index df09294de6..2234a62ac3 100644
--- a/lib/stdlib/doc/src/gen_event.xml
+++ b/lib/stdlib/doc/src/gen_event.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>gen_event</title>
@@ -630,12 +630,66 @@ gen_event:stop -----> Module:terminate/2
<p>The function should return the updated internal state.</p>
</desc>
</func>
+ <func>
+ <name>Module:format_status(Opt, [PDict, State]) -> Status</name>
+ <fsummary>Optional function for providing a term describing the
+ current event handler state.</fsummary>
+ <type>
+ <v>Opt = normal | terminate</v>
+ <v>PDict = [{Key, Value}]</v>
+ <v>State = term()</v>
+ <v>Status = term()</v>
+ </type>
+ <desc>
+ <note>
+ <p>This callback is optional, so event handler modules need
+ not export it. If a handler does not export this function,
+ the gen_event module uses the handler state directly for
+ the purposes described below.</p>
+ </note>
+ <p>This function is called by a gen_event process when:</p>
+ <list typed="bulleted">
+ <item>One
+ of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
+ is invoked to get the gen_event status. <c>Opt</c> is set
+ to the atom <c>normal</c> for this case.</item>
+ <item>The event handler terminates abnormally and gen_event
+ logs an error. <c>Opt</c> is set to the
+ atom <c>terminate</c> for this case.</item>
+ </list>
+ <p>This function is useful for customising the form and
+ appearance of the event handler state for these cases. An
+ event handler callback module wishing to customise
+ the <c>sys:get_status/1,2</c> return value as well as how
+ its state appears in termination error logs exports an
+ instance of <c>format_status/2</c> that returns a term
+ describing the current state of the event handler.</p>
+ <p><c>PDict</c> is the current value of the gen_event's
+ process dictionary.</p>
+ <p><c>State</c> is the internal state of the event
+ handler.</p>
+ <p>The function should return <c>Status</c>, a term that
+ customises the details of the current state of the event
+ handler. Any term is allowed for <c>Status</c>. The
+ gen_event module uses <c>Status</c> as follows:</p>
+ <list typed="bulleted">
+ <item>When <c>sys:get_status/1,2</c> is called, gen_event
+ ensures that its return value contains <c>Status</c> in
+ place of the event handler's actual state term.</item>
+ <item>When an event handler terminates abnormally, gen_event
+ logs <c>Status</c> in place of the event handler's actual
+ state term.</item>
+ </list>
+ <p>One use for this function is to return compact alternative
+ state representations to avoid having large state terms
+ printed in logfiles.</p>
+ </desc>
+ </func>
</funcs>
<section>
<title>SEE ALSO</title>
- <p><seealso marker="supervisor">supervisor(3)</seealso>,
+ <p><seealso marker="supervisor">supervisor(3)</seealso>,
<seealso marker="sys">sys(3)</seealso></p>
</section>
</erlref>
-
diff --git a/lib/stdlib/doc/src/gen_fsm.xml b/lib/stdlib/doc/src/gen_fsm.xml
index 739cd0bffd..d15383c621 100644
--- a/lib/stdlib/doc/src/gen_fsm.xml
+++ b/lib/stdlib/doc/src/gen_fsm.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>gen_fsm</title>
@@ -730,33 +730,58 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
</desc>
</func>
<func>
- <name>Module:format_status(normal, [PDict, StateData]) -> Status</name>
+ <name>Module:format_status(Opt, [PDict, StateData]) -> Status</name>
<fsummary>Optional function for providing a term describing the
current gen_fsm status.</fsummary>
<type>
+ <v>Opt = normal | terminate</v>
<v>PDict = [{Key, Value}]</v>
<v>StateData = term()</v>
- <v>Status = [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>
+ <note>
+ <p>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.</p>
+ </note>
+ <p>This function is called by a gen_fsm process when:</p>
+ <list typed="bulleted">
+ <item>One
+ of <seealso marker="sys#get_status/1">sys:get_status/1,2</seealso>
+ is invoked to get the gen_fsm status. <c>Opt</c> is set to
+ the atom <c>normal</c> for this case.</item>
+ <item>The gen_fsm terminates abnormally and logs an
+ error. <c>Opt</c> is set to the atom <c>terminate</c> for
+ this case.</item>
+ </list>
+ <p>This function is useful for customising the form and
+ appearance of the gen_fsm status for these cases. A callback
+ module wishing to customise the <c>sys:get_status/1,2</c>
+ return value as well as how its status appears in
+ termination error logs 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>
+ <p>The function should return <c>Status</c>, a term that
+ customises the details of the current state and status of
+ the gen_fsm. There are no restrictions on the
+ form <c>Status</c> can take, but for
+ the <c>sys:get_status/1,2</c> case (when <c>Opt</c>
+ is <c>normal</c>), the recommended form for
+ the <c>Status</c> value is <c>[{data, [{"StateData",
+ Term}]}]</c> where <c>Term</c> provides relevant details of
+ the gen_fsm state data. Following this recommendation isn't
+ required, but doing so will make the callback module status
+ consistent with the rest of the <c>sys:get_status/1,2</c>
+ return value.</p>
+ <p>One use for this function is to return compact alternative
+ state data representations to avoid having large state terms
+ printed in logfiles.</p>
</desc>
</func>
</funcs>
@@ -770,4 +795,3 @@ gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4
<seealso marker="sys">sys(3)</seealso></p>
</section>
</erlref>
-
diff --git a/lib/stdlib/doc/src/gen_server.xml b/lib/stdlib/doc/src/gen_server.xml
index 30c04d1d52..1045766e01 100644
--- a/lib/stdlib/doc/src/gen_server.xml
+++ b/lib/stdlib/doc/src/gen_server.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>gen_server</title>
@@ -599,32 +599,57 @@ gen_server:abcast -----> Module:handle_cast/2
</desc>
</func>
<func>
- <name>Module:format_status(normal, [PDict, State]) -> Status</name>
+ <name>Module:format_status(Opt, [PDict, State]) -> Status</name>
<fsummary>Optional function for providing a term describing the
current gen_server status.</fsummary>
<type>
+ <v>Opt = normal | terminate</v>
<v>PDict = [{Key, Value}]</v>
<v>State = term()</v>
- <v>Status = [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
+ <note>
+ <p>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.</p>
+ </note>
+ <p>This function is called by a gen_server process when:</p>
+ <list typed="bulleted">
+ <item>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>
+ is invoked to get the gen_server status. <c>Opt</c> is set
+ to the atom <c>normal</c> for this case.</item>
+ <item>The gen_server terminates abnormally and logs an
+ error. <c>Opt</c> is set to the atom <c>terminate</c> for this
+ case.</item>
+ </list>
+ <p>This function is useful for customising the form and
+ appearance of the gen_server status for these cases. A
+ callback module wishing to customise
+ the <c>sys:get_status/1,2</c> return value as well as how
+ its status appears in termination error logs 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>
+ <p>The function should return <c>Status</c>, a term that
+ customises the details of the current state and status of
+ the gen_server. There are no restrictions on the
+ form <c>Status</c> can take, but for
+ the <c>sys:get_status/1,2</c> case (when <c>Opt</c>
+ is <c>normal</c>), the recommended form for
+ the <c>Status</c> value is <c>[{data, [{"State",
+ Term}]}]</c> where <c>Term</c> provides relevant details of
+ the gen_server state. Following this recommendation isn't
+ required, but doing so will make the callback module status
+ consistent with the rest of the <c>sys:get_status/1,2</c>
+ return value.</p>
+ <p>One use for this function is to return compact alternative
+ state representations to avoid having large state terms
+ printed in logfiles.</p>
</desc>
</func>
</funcs>
diff --git a/lib/stdlib/doc/src/lists.xml b/lib/stdlib/doc/src/lists.xml
index 855a7e0244..a273a2301f 100644
--- a/lib/stdlib/doc/src/lists.xml
+++ b/lib/stdlib/doc/src/lists.xml
@@ -443,7 +443,7 @@ flatmap(Fun, List1) ->
<desc>
<p>Returns a list containing the sorted elements of the list
<c>TupleList1</c>. Sorting is performed on the <c>N</c>th
- element of the tuples.</p>
+ element of the tuples. The sort is stable.</p>
</desc>
</func>
<func>
@@ -466,7 +466,7 @@ flatmap(Fun, List1) ->
</desc>
</func>
<func>
- <name>keytake(Key, N, TupleList1) -> {value, Tuple, TupleList2}
+ <name>keytake(Key, N, TupleList1) -> {value, Tuple, TupleList2}
| false</name>
<fsummary>Extract an element from a list of tuples</fsummary>
<type>
@@ -840,7 +840,7 @@ length(lists:seq(From, To, Incr)) == (To-From+Incr) div Incr</code>
<c>Pred</c>. <c>splitwith/2</c> behaves as if it is defined
as follows:</p>
<code type="none">
-splitwith(Pred, List) ->
+splitwith(Pred, List) ->
{takewhile(Pred, List), dropwhile(Pred, List)}.</code>
<p>Examples:</p>
<pre>
diff --git a/lib/stdlib/doc/src/re.xml b/lib/stdlib/doc/src/re.xml
index 4d2a0e0995..80adc3e347 100644
--- a/lib/stdlib/doc/src/re.xml
+++ b/lib/stdlib/doc/src/re.xml
@@ -80,7 +80,11 @@
- a unicode_binary is allowed as the tail of the list</code>
<code type="none">
- mp() = Opaque datatype containing a compiled regular expression.</code>
+ mp() = Opaque datatype containing a compiled regular expression.
+ - The mp() is guaranteed to be a tuple() having the atom
+ 're_pattern' as it's first element, to allow for matching in
+ guards. The arity of the tuple() or the content of the other fields
+ is however not to be trusted.</code>
</section>
<funcs>
<func>
diff --git a/lib/stdlib/doc/src/ref_man.xml b/lib/stdlib/doc/src/ref_man.xml
index f6ae368e92..85aae6151d 100644
--- a/lib/stdlib/doc/src/ref_man.xml
+++ b/lib/stdlib/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>STDLIB Reference Manual</title>
@@ -37,6 +37,7 @@
<xi:include href="array.xml"/>
<xi:include href="base64.xml"/>
<xi:include href="beam_lib.xml"/>
+ <xi:include href="binary.xml"/>
<xi:include href="c.xml"/>
<xi:include href="calendar.xml"/>
<xi:include href="dets.xml"/>
diff --git a/lib/stdlib/src/Makefile b/lib/stdlib/src/Makefile
index 237818c08b..600303d7e1 100644
--- a/lib/stdlib/src/Makefile
+++ b/lib/stdlib/src/Makefile
@@ -43,6 +43,7 @@ MODULES= \
array \
base64 \
beam_lib \
+ binary \
c \
calendar \
dets \
diff --git a/lib/stdlib/src/beam_lib.erl b/lib/stdlib/src/beam_lib.erl
index 820afd3739..91ff2438c6 100644
--- a/lib/stdlib/src/beam_lib.erl
+++ b/lib/stdlib/src/beam_lib.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(beam_lib).
@@ -41,12 +41,11 @@
terminate/2,code_change/3]).
-export([make_crypto_key/2, get_crypto_key/1]). %Utilities used by compiler
+-export_type([attrib_entry/0, compinfo_entry/0, labeled_entry/0]).
+
-import(lists, [append/1, delete/2, foreach/2, keysort/2,
member/2, reverse/1, sort/1, splitwith/2]).
--include_lib("kernel/include/file.hrl").
--include("erl_compile.hrl").
-
%%-------------------------------------------------------------------------
-type beam() :: module() | file:filename() | binary().
@@ -331,13 +330,11 @@ beam_files(Dir) ->
%% -> ok | throw(Error)
cmp_files(File1, File2) ->
- {ok, {M1, L1}} = read_significant_chunks(File1),
- {ok, {M2, L2}} = read_significant_chunks(File2),
+ {ok, {M1, L1}} = read_all_but_useless_chunks(File1),
+ {ok, {M2, L2}} = read_all_but_useless_chunks(File2),
if
M1 =:= M2 ->
- List1 = filter_funtab(L1),
- List2 = filter_funtab(L2),
- cmp_lists(List1, List2);
+ cmp_lists(L1, L2);
true ->
error({modules_different, M1, M2})
end.
@@ -408,6 +405,20 @@ pad(Size) ->
end.
%% -> {ok, {Module, Chunks}} | throw(Error)
+read_all_but_useless_chunks(File0) when is_atom(File0);
+ is_list(File0);
+ is_binary(File0) ->
+ File = beam_filename(File0),
+ {ok, Module, ChunkIds0} = scan_beam(File, info),
+ ChunkIds = [Name || {Name,_,_} <- ChunkIds0,
+ not is_useless_chunk(Name)],
+ {ok, Module, Chunks} = scan_beam(File, ChunkIds),
+ {ok, {Module, lists:reverse(Chunks)}}.
+
+is_useless_chunk("CInf") -> true;
+is_useless_chunk(_) -> false.
+
+%% -> {ok, {Module, Chunks}} | throw(Error)
read_significant_chunks(File) ->
case read_chunk_data(File, significant_chunks(), [allow_missing_chunks]) of
{ok, {Module, Chunks0}} ->
diff --git a/lib/stdlib/src/binary.erl b/lib/stdlib/src/binary.erl
new file mode 100644
index 0000000000..f6489788b2
--- /dev/null
+++ b/lib/stdlib/src/binary.erl
@@ -0,0 +1,177 @@
+%%
+%% %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(binary).
+%%
+%% The following functions implemented as BIF's
+%% binary:compile_pattern/1
+%% binary:match/{2,3}
+%% binary:matches/{2,3}
+%% binary:longest_common_prefix/1
+%% binary:longest_common_suffix/1
+%% binary:first/1
+%% binary:last/1
+%% binary:at/2
+%% binary:part/{2,3}
+%% binary:bin_to_list/{1,2,3}
+%% binary:list_to_bin/1
+%% binary:copy/{1,2}
+%% binary:referenced_byte_size/1
+%% binary:decode_unsigned/{1,2}
+%% - Not yet:
+%%
+%% Implemented in this module:
+-export([split/2,split/3,replace/3,replace/4]).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% split
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+split(H,N) ->
+ split(H,N,[]).
+split(Haystack,Needles,Options) ->
+ try
+ {Part,Global,Trim} = get_opts_split(Options,{no,false,false}),
+ Moptlist = case Part of
+ no ->
+ [];
+ {A,B} ->
+ [{scope,{A,B}}]
+ end,
+ MList = if
+ Global ->
+ binary:matches(Haystack,Needles,Moptlist);
+ true ->
+ case binary:match(Haystack,Needles,Moptlist) of
+ nomatch -> [];
+ Match -> [Match]
+ end
+ end,
+ do_split(Haystack,MList,0,Trim)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+do_split(H,[],N,true) when N >= byte_size(H) ->
+ [];
+do_split(H,[],N,_) ->
+ [binary:part(H,{N,byte_size(H)-N})];
+do_split(H,[{A,B}|T],N,Trim) ->
+ case binary:part(H,{N,A-N}) of
+ <<>> ->
+ Rest = do_split(H,T,A+B,Trim),
+ case {Trim, Rest} of
+ {true,[]} ->
+ [];
+ _ ->
+ [<<>> | Rest]
+ end;
+ Oth ->
+ [Oth | do_split(H,T,A+B,Trim)]
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% replace
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+replace(H,N,R) ->
+ replace(H,N,R,[]).
+replace(Haystack,Needles,Replacement,Options) ->
+ try
+ true = is_binary(Replacement), % Make badarg instead of function clause
+ {Part,Global,Insert} = get_opts_replace(Options,{no,false,[]}),
+ Moptlist = case Part of
+ no ->
+ [];
+ {A,B} ->
+ [{scope,{A,B}}]
+ end,
+ MList = if
+ Global ->
+ binary:matches(Haystack,Needles,Moptlist);
+ true ->
+ case binary:match(Haystack,Needles,Moptlist) of
+ nomatch -> [];
+ Match -> [Match]
+ end
+ end,
+ ReplList = case Insert of
+ [] ->
+ Replacement;
+ Y when is_integer(Y) ->
+ splitat(Replacement,0,[Y]);
+ Li when is_list(Li) ->
+ splitat(Replacement,0,lists:sort(Li))
+ end,
+ erlang:iolist_to_binary(do_replace(Haystack,MList,ReplList,0))
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+
+do_replace(H,[],_,N) ->
+ [binary:part(H,{N,byte_size(H)-N})];
+do_replace(H,[{A,B}|T],Replacement,N) ->
+ [binary:part(H,{N,A-N}),
+ if
+ is_list(Replacement) ->
+ do_insert(Replacement, binary:part(H,{A,B}));
+ true ->
+ Replacement
+ end
+ | do_replace(H,T,Replacement,A+B)].
+
+do_insert([X],_) ->
+ [X];
+do_insert([H|T],R) ->
+ [H,R|do_insert(T,R)].
+
+splitat(H,N,[]) ->
+ [binary:part(H,{N,byte_size(H)-N})];
+splitat(H,N,[I|T]) ->
+ [binary:part(H,{N,I-N})|splitat(H,I,T)].
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Simple helper functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+get_opts_split([],{Part,Global,Trim}) ->
+ {Part,Global,Trim};
+get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim}) ->
+ get_opts_split(T,{{A,B},Global,Trim});
+get_opts_split([global | T],{Part,_Global,Trim}) ->
+ get_opts_split(T,{Part,true,Trim});
+get_opts_split([trim | T],{Part,Global,_Trim}) ->
+ get_opts_split(T,{Part,Global,true});
+get_opts_split(_,_) ->
+ throw(badopt).
+
+get_opts_replace([],{Part,Global,Insert}) ->
+ {Part,Global,Insert};
+get_opts_replace([{scope,{A,B}} | T],{_Part,Global,Insert}) ->
+ get_opts_replace(T,{{A,B},Global,Insert});
+get_opts_replace([global | T],{Part,_Global,Insert}) ->
+ get_opts_replace(T,{Part,true,Insert});
+get_opts_replace([{insert_replaced,N} | T],{Part,Global,_Insert}) ->
+ get_opts_replace(T,{Part,Global,N});
+get_opts_replace(_,_) ->
+ throw(badopt).
+
diff --git a/lib/stdlib/src/dets.erl b/lib/stdlib/src/dets.erl
index 7f1c13770b..4584b8184f 100644
--- a/lib/stdlib/src/dets.erl
+++ b/lib/stdlib/src/dets.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(dets).
@@ -88,6 +88,7 @@
%% Not documented, or not ready for publication.
-export([lookup_keys/2]).
+-export_type([tab_name/0]).
-compile({inline, [{einval,2},{badarg,2},{undefined,1},
{badarg_exit,2},{lookup_reply,2}]}).
diff --git a/lib/stdlib/src/digraph.erl b/lib/stdlib/src/digraph.erl
index 9bdea671a9..b5f52da921 100644
--- a/lib/stdlib/src/digraph.erl
+++ b/lib/stdlib/src/digraph.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(digraph).
@@ -36,6 +36,8 @@
-export([get_short_path/3, get_short_cycle/2]).
+-export_type([d_type/0, vertex/0]).
+
-record(digraph, {vtab = notable :: ets:tab(),
etab = notable :: ets:tab(),
ntab = notable :: ets:tab(),
diff --git a/lib/stdlib/src/edlin.erl b/lib/stdlib/src/edlin.erl
index 6cb441dbed..026bd9038f 100644
--- a/lib/stdlib/src/edlin.erl
+++ b/lib/stdlib/src/edlin.erl
@@ -24,6 +24,7 @@
-export([init/0,start/1,edit_line/2,prefix_arg/1]).
-export([erase_line/1,erase_inp/1,redraw_line/1]).
-export([length_before/1,length_after/1,prompt/1]).
+-export([current_line/1]).
%%-export([expand/1]).
-export([edit_line1/2]).
@@ -421,6 +422,7 @@ over_paren_auto([], _, _, _) ->
%% length_before(Line)
%% length_after(Line)
%% prompt(Line)
+%% current_line(Line)
%% Various functions for accessing bits of a line.
erase_line({line,Pbs,{Bef,Aft},_}) ->
@@ -447,6 +449,9 @@ length_after({line,_,{_Bef,Aft},_}) ->
prompt({line,Pbs,_,_}) ->
Pbs.
+current_line({line,_,{Bef, Aft},_}) ->
+ reverse(Bef, Aft ++ "\n").
+
%% %% expand(CurrentBefore) ->
%% %% {yes,Expansion} | no
%% %% Try to expand the word before as either a module name or a function
diff --git a/lib/stdlib/src/epp.erl b/lib/stdlib/src/epp.erl
index f144cbb938..81b2431f40 100644
--- a/lib/stdlib/src/epp.erl
+++ b/lib/stdlib/src/epp.erl
@@ -111,6 +111,8 @@ format_error({bad,W}) ->
io_lib:format("badly formed '~s'", [W]);
format_error(missing_parenthesis) ->
io_lib:format("badly formed define: missing closing right parenthesis",[]);
+format_error(premature_end) ->
+ "premature end";
format_error({call,What}) ->
io_lib:format("illegal macro call '~s'",[What]);
format_error({undefined,M,none}) ->
@@ -163,7 +165,7 @@ parse_file(Epp) ->
case normalize_typed_record_fields(Fields) of
{typed, NewFields} ->
[{attribute, La, record, {Record, NewFields}},
- {attribute, La, type,
+ {attribute, La, type,
{{record, Record}, Fields, []}}
|parse_file(Epp)];
not_typed ->
@@ -188,7 +190,7 @@ normalize_typed_record_fields([], NewFields, Typed) ->
true -> {typed, lists:reverse(NewFields)};
false -> not_typed
end;
-normalize_typed_record_fields([{typed_record_field,Field,_}|Rest],
+normalize_typed_record_fields([{typed_record_field,Field,_}|Rest],
NewFields, _Typed) ->
normalize_typed_record_fields(Rest, [Field|NewFields], true);
normalize_typed_record_fields([Field|Rest], NewFields, Typed) ->
@@ -324,7 +326,7 @@ wait_req_scan(St) ->
wait_req_skip(St, Sis) ->
From = wait_request(St),
skip_toks(From, St, Sis).
-
+
%% enter_file(Path, FileName, IncludeToken, From, EppState)
%% leave_file(From, EppState)
%% Handle entering and leaving included files. Notify caller when the
@@ -380,16 +382,16 @@ file_name(N) when is_atom(N) ->
leave_file(From, St) ->
case St#epp.istk of
- [I|Cis] ->
+ [I|Cis] ->
epp_reply(From,
- {error,{St#epp.location,epp,
+ {error,{St#epp.location,epp,
{illegal,"unterminated",I}}}),
leave_file(wait_request(St),St#epp{istk=Cis});
[] ->
case St#epp.sstk of
[OldSt|Sts] ->
close_file(St),
- enter_file_reply(From, OldSt#epp.name,
+ enter_file_reply(From, OldSt#epp.name,
OldSt#epp.location, OldSt#epp.location),
Ms = dict:store({atom,'FILE'},
{none,
@@ -491,9 +493,9 @@ scan_extends(_Ts, _As, Ms) -> Ms.
%% scan_define(Tokens, DefineToken, From, EppState)
-scan_define([{'(',_Lp},{Type,_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 catch macro_expansion(Toks) of
+ case catch macro_expansion(Toks, Lc) of
Expansion when is_list(Expansion) ->
case dict:find({atom,M}, St#epp.macs) of
{ok, Defs} when is_list(Defs) ->
@@ -608,7 +610,7 @@ scan_undef(_Toks, Undef, From, St) ->
%% scan_include(Tokens, IncludeToken, From, St)
-scan_include([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], Inc,
+scan_include([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}], Inc,
From, St) ->
NewName = expand_var(NewName0),
enter_file(St#epp.path, NewName, Inc, From, St);
@@ -644,7 +646,7 @@ scan_include_lib([{'(',_Llp},{string,_Lf,NewName0},{')',_Lrp},{dot,_Ld}],
case file:open(LibName, [read]) of
{ok,NewF} ->
ExtraPath = [filename:dirname(LibName)],
- wait_req_scan(enter_file2(NewF, LibName, From,
+ wait_req_scan(enter_file2(NewF, LibName, From,
St, Loc, ExtraPath));
{error,_E2} ->
epp_reply(From,
@@ -773,7 +775,7 @@ scan_file(_Toks, Tf, From, St) ->
new_location(Ln, Le, Lf) when is_integer(Lf) ->
Ln+(Le-Lf);
-new_location(Ln, {Le,_}, {Lf,_}) ->
+new_location(Ln, {Le,_}, {Lf,_}) ->
{Ln+(Le-Lf),1}.
%% skip_toks(From, EppState, SkipIstack)
@@ -814,22 +816,23 @@ skip_else(_Else, From, St, Sis) ->
skip_toks(From, St, Sis).
%% macro_pars(Tokens, ArgStack)
-%% macro_expansion(Tokens)
+%% macro_expansion(Tokens, Line)
%% Extract the macro parameters and the expansion from a macro definition.
-macro_pars([{')',_Lp}, {',',_Ld}|Ex], Args) ->
- {ok, {lists:reverse(Args), macro_expansion(Ex)}};
-macro_pars([{var,_,Name}, {')',_Lp}, {',',_Ld}|Ex], Args) ->
+macro_pars([{')',_Lp}, {',',Ld}|Ex], Args) ->
+ {ok, {lists:reverse(Args), macro_expansion(Ex, Ld)}};
+macro_pars([{var,_,Name}, {')',_Lp}, {',',Ld}|Ex], Args) ->
false = lists:member(Name, Args), %Prolog is nice
- {ok, {lists:reverse([Name|Args]), macro_expansion(Ex)}};
+ {ok, {lists:reverse([Name|Args]), macro_expansion(Ex, Ld)}};
macro_pars([{var,_L,Name}, {',',_}|Ts], Args) ->
- false = lists:member(Name, Args),
+ false = lists:member(Name, Args),
macro_pars(Ts, [Name|Args]).
-macro_expansion([{')',_Lp},{dot,_Ld}]) -> [];
-macro_expansion([{dot,Ld}]) -> throw({error,Ld,missing_parenthesis});
-macro_expansion([T|Ts]) ->
- [T|macro_expansion(Ts)].
+macro_expansion([{')',_Lp},{dot,_Ld}], _L0) -> [];
+macro_expansion([{dot,Ld}], _L0) -> throw({error,Ld,missing_parenthesis});
+macro_expansion([T|Ts], _L0) ->
+ [T|macro_expansion(Ts, element(2, T))];
+macro_expansion([], L0) -> throw({error,L0,premature_end}).
%% expand_macros(Tokens, Macros)
%% expand_macro(Tokens, MacroToken, RestTokens)
@@ -1084,11 +1087,11 @@ epp_reply(From, Rep) ->
wait_epp_reply(Epp, Mref) ->
receive
- {epp_reply,Epp,Rep} ->
+ {epp_reply,Epp,Rep} ->
erlang:demonitor(Mref),
receive {'DOWN',Mref,_,_,_} -> ok after 0 -> ok end,
Rep;
- {'DOWN',Mref,_,_,E} ->
+ {'DOWN',Mref,_,_,E} ->
receive {epp_reply,Epp,Rep} -> Rep
after 0 -> exit(E)
end
@@ -1145,7 +1148,7 @@ get_line({Line,_Column}) ->
%% mainly aimed at yecc, the parser generator, which uses the -file
%% attribute to get correct lines in messages referring to code
%% supplied by the user (actions etc in .yrl files).
-%%
+%%
%% In a perfect world (read: perfectly implemented applications such
%% as Xref, Cover, Debugger, etc.) it would not be necessary to
%% distinguish -file attributes from epp and the input file. The
@@ -1165,7 +1168,7 @@ get_line({Line,_Column}) ->
%% have been output by epp (corresponding to -include and
%% -include_lib) are kept, but the user's -file attributes are
%% removed. This seems sufficient for now.
-%%
+%%
%% It turns out to be difficult to distinguish -file attributes in the
%% input file from the ones added by epp unless some action is taken.
%% The (less than perfect) solution employed is to let epp assign
@@ -1177,7 +1180,7 @@ get_line({Line,_Column}) ->
interpret_file_attribute(Forms) ->
interpret_file_attr(Forms, 0, []).
-interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms],
+interpret_file_attr([{attribute,Loc,file,{File,Line}}=Form | Forms],
Delta, Fs) ->
{line, L} = erl_scan:attributes_info(Loc, line),
if
diff --git a/lib/stdlib/src/erl_compile.erl b/lib/stdlib/src/erl_compile.erl
index d9d15e05f8..abff37e4bc 100644
--- a/lib/stdlib/src/erl_compile.erl
+++ b/lib/stdlib/src/erl_compile.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_compile).
@@ -23,6 +23,8 @@
-export([compile_cmdline/1]).
+-export_type([cmd_line_arg/0]).
+
%% Mapping from extension to {M,F} to run the correct compiler.
compiler(".erl") -> {compile, compile};
diff --git a/lib/stdlib/src/erl_expand_records.erl b/lib/stdlib/src/erl_expand_records.erl
index a38b7639d8..18c467db81 100644
--- a/lib/stdlib/src/erl_expand_records.erl
+++ b/lib/stdlib/src/erl_expand_records.erl
@@ -95,8 +95,9 @@ forms([F | Fs0], St0) ->
forms([], St) -> {[],St}.
clauses([{clause,Line,H0,G0,B0} | Cs0], St0) ->
- {H,St1} = head(H0, St0),
- {G,St2} = guard(G0, St1),
+ {H1,St1} = head(H0, St0),
+ {G1,St2} = guard(G0, St1),
+ {H,G} = optimize_is_record(H1, G1),
{B,St3} = exprs(B0, St2),
{Cs,St4} = clauses(Cs0, St3),
{[{clause,Line,H,G,B} | Cs],St4};
@@ -800,5 +801,132 @@ imported(F, A, St) ->
error -> no
end.
+%%%
+%%% Replace is_record/3 in guards with matching if possible.
+%%%
+
+optimize_is_record(H0, G0) ->
+ case opt_rec_vars(G0) of
+ [] ->
+ {H0,G0};
+ Rs0 ->
+ {H,Rs} = opt_pattern_list(H0, Rs0),
+ G = opt_remove(G0, Rs),
+ {H,G}
+ end.
+
+
+%% opt_rec_vars(Guards) -> Vars.
+%% Search through the guard expression, looking for
+%% variables referenced in those is_record/3 calls that
+%% will fail the entire guard if they evaluate to 'false'
+%%
+%% In the following code
+%%
+%% f(X, Y, Z) when is_record(X, r1) andalso
+%% (is_record(Y, r2) orelse is_record(Z, r3))
+%%
+%% the entire guard will be false if the record test for
+%% X fails, and the clause can be rewritten to:
+%%
+%% f({r1,...}=X, Y, Z) when true andalso
+%% (is_record(Y, r2) or is_record(Z, r3))
+%%
+opt_rec_vars([G|Gs]) ->
+ Rs = opt_rec_vars_1(G, orddict:new()),
+ opt_rec_vars(Gs, Rs);
+opt_rec_vars([]) -> orddict:new().
+
+opt_rec_vars([G|Gs], Rs0) ->
+ Rs1 = opt_rec_vars_1(G, orddict:new()),
+ Rs = ordsets:intersection(Rs0, Rs1),
+ opt_rec_vars(Gs, Rs);
+opt_rec_vars([], Rs) -> Rs.
+
+opt_rec_vars_1([T|Ts], Rs0) ->
+ Rs = opt_rec_vars_2(T, Rs0),
+ opt_rec_vars_1(Ts, Rs);
+opt_rec_vars_1([], Rs) -> Rs.
+
+opt_rec_vars_2({op,_,'and',A1,A2}, Rs) ->
+ opt_rec_vars_1([A1,A2], Rs);
+opt_rec_vars_2({op,_,'andalso',A1,A2}, Rs) ->
+ opt_rec_vars_1([A1,A2], Rs);
+opt_rec_vars_2({op,_,'orelse',Arg,{atom,_,fail}}, Rs) ->
+ %% Since the second argument guarantees failure,
+ %% it is safe to inspect the first argument.
+ opt_rec_vars_2(Arg, Rs);
+opt_rec_vars_2({call,_,{remote,_,{atom,_,erlang},{atom,_,is_record}},
+ [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}, Rs) ->
+ orddict:store(V, {Tag,Sz}, Rs);
+opt_rec_vars_2({call,_,{atom,_,is_record},
+ [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}, Rs) ->
+ orddict:store(V, {Tag,Sz}, Rs);
+opt_rec_vars_2(_, Rs) -> Rs.
+
+opt_pattern_list(Ps, Rs) ->
+ opt_pattern_list(Ps, Rs, []).
+
+opt_pattern_list([P0|Ps], Rs0, Acc) ->
+ {P,Rs} = opt_pattern(P0, Rs0),
+ opt_pattern_list(Ps, Rs, [P|Acc]);
+opt_pattern_list([], Rs, Acc) ->
+ {reverse(Acc),Rs}.
+
+opt_pattern({var,_,V}=Var, Rs0) ->
+ case orddict:find(V, Rs0) of
+ {ok,{Tag,Sz}} ->
+ Rs = orddict:store(V, {remove,Tag,Sz}, Rs0),
+ {opt_var(Var, Tag, Sz),Rs};
+ _ ->
+ {Var,Rs0}
+ end;
+opt_pattern({cons,Line,H0,T0}, Rs0) ->
+ {H,Rs1} = opt_pattern(H0, Rs0),
+ {T,Rs} = opt_pattern(T0, Rs1),
+ {{cons,Line,H,T},Rs};
+opt_pattern({tuple,Line,Es0}, Rs0) ->
+ {Es,Rs} = opt_pattern_list(Es0, Rs0),
+ {{tuple,Line,Es},Rs};
+opt_pattern({match,Line,Pa0,Pb0}, Rs0) ->
+ {Pa,Rs1} = opt_pattern(Pa0, Rs0),
+ {Pb,Rs} = opt_pattern(Pb0, Rs1),
+ {{match,Line,Pa,Pb},Rs};
+opt_pattern(P, Rs) -> {P,Rs}.
+
+opt_var({var,Line,_}=Var, Tag, Sz) ->
+ Rp = record_pattern(2, -1, ignore, Sz, Line, [{atom,Line,Tag}]),
+ {match,Line,{tuple,Line,Rp},Var}.
+
+opt_remove(Gs, Rs) ->
+ [opt_remove_1(G, Rs) || G <- Gs].
+
+opt_remove_1(Ts, Rs) ->
+ [opt_remove_2(T, Rs) || T <- Ts].
+
+opt_remove_2({op,L,'and'=Op,A1,A2}, Rs) ->
+ {op,L,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)};
+opt_remove_2({op,L,'andalso'=Op,A1,A2}, Rs) ->
+ {op,L,Op,opt_remove_2(A1, Rs),opt_remove_2(A2, Rs)};
+opt_remove_2({op,L,'orelse',A1,A2}, Rs) ->
+ {op,L,'orelse',opt_remove_2(A1, Rs),A2};
+opt_remove_2({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}},
+ [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}=A, Rs) ->
+ case orddict:find(V, Rs) of
+ {ok,{remove,Tag,Sz}} ->
+ {atom,Line,true};
+ _ ->
+ A
+ end;
+opt_remove_2({call,Line,{atom,_,is_record},
+ [{var,_,V},{atom,_,Tag},{integer,_,Sz}]}=A, Rs) ->
+ case orddict:find(V, Rs) of
+ {ok,{remove,Tag,Sz}} ->
+ {atom,Line,true};
+ _ ->
+ A
+ end;
+opt_remove_2(A, _) -> A.
+
neg_line(L) ->
erl_parse:set_line(L, fun(Line) -> -abs(Line) end).
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl
index 16173d8210..bf6e5bc5ca 100644
--- a/lib/stdlib/src/erl_internal.erl
+++ b/lib/stdlib/src/erl_internal.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(erl_internal).
@@ -48,7 +48,7 @@
%%
-export([bif/2,bif/3,guard_bif/2,
- type_test/2,new_type_test/2,old_type_test/2]).
+ type_test/2,new_type_test/2,old_type_test/2,old_bif/2]).
-export([arith_op/2,bool_op/2,comp_op/2,list_op/2,send_op/2,op_type/2]).
%%---------------------------------------------------------------------------
@@ -87,6 +87,8 @@ guard_bif(is_reference, 1) -> true;
guard_bif(is_tuple, 1) -> true;
guard_bif(is_record, 2) -> true;
guard_bif(is_record, 3) -> true;
+guard_bif(binary_part, 2) -> true;
+guard_bif(binary_part, 3) -> true;
guard_bif(Name, A) when is_atom(Name), is_integer(A) -> false.
%% Erlang type tests.
@@ -229,11 +231,14 @@ bif(apply, 2) -> true;
bif(apply, 3) -> true;
bif(atom_to_binary, 2) -> true;
bif(atom_to_list, 1) -> true;
+bif(binary_part, 2) -> true;
+bif(binary_part, 3) -> true;
bif(binary_to_atom, 2) -> true;
bif(binary_to_existing_atom, 2) -> true;
bif(binary_to_list, 1) -> true;
bif(binary_to_list, 3) -> true;
bif(binary_to_term, 1) -> true;
+bif(binary_to_term, 2) -> true;
bif(bitsize, 1) -> true;
bif(bit_size, 1) -> true;
bif(bitstring_to_list, 1) -> true;
@@ -294,6 +299,8 @@ bif(list_to_pid, 1) -> true;
bif(list_to_tuple, 1) -> true;
bif(load_module, 2) -> true;
bif(make_ref, 0) -> true;
+bif(max,2) -> true;
+bif(min,2) -> true;
bif(module_loaded, 1) -> true;
bif(monitor_node, 2) -> true;
bif(node, 0) -> true;
@@ -305,6 +312,7 @@ bif(open_port, 2) -> true;
bif(pid_to_list, 1) -> true;
bif(port_close, 1) -> true;
bif(port_command, 2) -> true;
+bif(port_command, 3) -> true;
bif(port_connect, 2) -> true;
bif(port_control, 3) -> true;
bif(pre_loaded, 0) -> true;
@@ -349,3 +357,134 @@ bif(unlink, 1) -> true;
bif(unregister, 1) -> true;
bif(whereis, 1) -> true;
bif(Name, A) when is_atom(Name), is_integer(A) -> false.
+
+-spec old_bif(Name::atom(), Arity::arity()) -> boolean().
+%% Returns true if erlang:Name/Arity is an old (pre R14) auto-imported BIF, false otherwise.
+%% Use erlang:is_bultin(Mod, Name, Arity) to find whether a function is a BIF
+%% (meaning implemented in C) or not.
+
+old_bif(abs, 1) -> true;
+old_bif(apply, 2) -> true;
+old_bif(apply, 3) -> true;
+old_bif(atom_to_binary, 2) -> true;
+old_bif(atom_to_list, 1) -> true;
+old_bif(binary_to_atom, 2) -> true;
+old_bif(binary_to_existing_atom, 2) -> true;
+old_bif(binary_to_list, 1) -> true;
+old_bif(binary_to_list, 3) -> true;
+old_bif(binary_to_term, 1) -> true;
+old_bif(bitsize, 1) -> true;
+old_bif(bit_size, 1) -> true;
+old_bif(bitstring_to_list, 1) -> true;
+old_bif(byte_size, 1) -> true;
+old_bif(check_process_code, 2) -> true;
+old_bif(concat_binary, 1) -> true;
+old_bif(date, 0) -> true;
+old_bif(delete_module, 1) -> true;
+old_bif(disconnect_node, 1) -> true;
+old_bif(element, 2) -> true;
+old_bif(erase, 0) -> true;
+old_bif(erase, 1) -> true;
+old_bif(exit, 1) -> true;
+old_bif(exit, 2) -> true;
+old_bif(float, 1) -> true;
+old_bif(float_to_list, 1) -> true;
+old_bif(garbage_collect, 0) -> true;
+old_bif(garbage_collect, 1) -> true;
+old_bif(get, 0) -> true;
+old_bif(get, 1) -> true;
+old_bif(get_keys, 1) -> true;
+old_bif(group_leader, 0) -> true;
+old_bif(group_leader, 2) -> true;
+old_bif(halt, 0) -> true;
+old_bif(halt, 1) -> true;
+old_bif(hd, 1) -> true;
+old_bif(integer_to_list, 1) -> true;
+old_bif(iolist_size, 1) -> true;
+old_bif(iolist_to_binary, 1) -> true;
+old_bif(is_alive, 0) -> true;
+old_bif(is_process_alive, 1) -> true;
+old_bif(is_atom, 1) -> true;
+old_bif(is_boolean, 1) -> true;
+old_bif(is_binary, 1) -> true;
+old_bif(is_bitstr, 1) -> true;
+old_bif(is_bitstring, 1) -> true;
+old_bif(is_float, 1) -> true;
+old_bif(is_function, 1) -> true;
+old_bif(is_function, 2) -> true;
+old_bif(is_integer, 1) -> true;
+old_bif(is_list, 1) -> true;
+old_bif(is_number, 1) -> true;
+old_bif(is_pid, 1) -> true;
+old_bif(is_port, 1) -> true;
+old_bif(is_reference, 1) -> true;
+old_bif(is_tuple, 1) -> true;
+old_bif(is_record, 2) -> true;
+old_bif(is_record, 3) -> true;
+old_bif(length, 1) -> true;
+old_bif(link, 1) -> true;
+old_bif(list_to_atom, 1) -> true;
+old_bif(list_to_binary, 1) -> true;
+old_bif(list_to_bitstring, 1) -> true;
+old_bif(list_to_existing_atom, 1) -> true;
+old_bif(list_to_float, 1) -> true;
+old_bif(list_to_integer, 1) -> true;
+old_bif(list_to_pid, 1) -> true;
+old_bif(list_to_tuple, 1) -> true;
+old_bif(load_module, 2) -> true;
+old_bif(make_ref, 0) -> true;
+old_bif(module_loaded, 1) -> true;
+old_bif(monitor_node, 2) -> true;
+old_bif(node, 0) -> true;
+old_bif(node, 1) -> true;
+old_bif(nodes, 0) -> true;
+old_bif(nodes, 1) -> true;
+old_bif(now, 0) -> true;
+old_bif(open_port, 2) -> true;
+old_bif(pid_to_list, 1) -> true;
+old_bif(port_close, 1) -> true;
+old_bif(port_command, 2) -> true;
+old_bif(port_connect, 2) -> true;
+old_bif(port_control, 3) -> true;
+old_bif(pre_loaded, 0) -> true;
+old_bif(process_flag, 2) -> true;
+old_bif(process_flag, 3) -> true;
+old_bif(process_info, 1) -> true;
+old_bif(process_info, 2) -> true;
+old_bif(processes, 0) -> true;
+old_bif(purge_module, 1) -> true;
+old_bif(put, 2) -> true;
+old_bif(register, 2) -> true;
+old_bif(registered, 0) -> true;
+old_bif(round, 1) -> true;
+old_bif(self, 0) -> true;
+old_bif(setelement, 3) -> true;
+old_bif(size, 1) -> true;
+old_bif(spawn, 1) -> true;
+old_bif(spawn, 2) -> true;
+old_bif(spawn, 3) -> true;
+old_bif(spawn, 4) -> true;
+old_bif(spawn_link, 1) -> true;
+old_bif(spawn_link, 2) -> true;
+old_bif(spawn_link, 3) -> true;
+old_bif(spawn_link, 4) -> true;
+old_bif(spawn_monitor, 1) -> true;
+old_bif(spawn_monitor, 3) -> true;
+old_bif(spawn_opt, 2) -> true;
+old_bif(spawn_opt, 3) -> true;
+old_bif(spawn_opt, 4) -> true;
+old_bif(spawn_opt, 5) -> true;
+old_bif(split_binary, 2) -> true;
+old_bif(statistics, 1) -> true;
+old_bif(term_to_binary, 1) -> true;
+old_bif(term_to_binary, 2) -> true;
+old_bif(throw, 1) -> true;
+old_bif(time, 0) -> true;
+old_bif(tl, 1) -> true;
+old_bif(trunc, 1) -> true;
+old_bif(tuple_size, 1) -> true;
+old_bif(tuple_to_list, 1) -> true;
+old_bif(unlink, 1) -> true;
+old_bif(unregister, 1) -> true;
+old_bif(whereis, 1) -> true;
+old_bif(Name, A) when is_atom(Name), is_integer(A) -> false.
diff --git a/lib/stdlib/src/erl_lint.erl b/lib/stdlib/src/erl_lint.erl
index 94ad560549..6bbb52ebae 100644
--- a/lib/stdlib/src/erl_lint.erl
+++ b/lib/stdlib/src/erl_lint.erl
@@ -40,7 +40,7 @@
%% Value.
%% The option handling functions.
--spec bool_option(atom(), atom(), boolean(), [_]) -> boolean().
+-spec bool_option(atom(), atom(), boolean(), [compile:option()]) -> boolean().
bool_option(On, Off, Default, Opts) ->
foldl(fun (Opt, _Def) when Opt =:= On -> true;
@@ -72,6 +72,10 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
%%-define(DEBUGF(X,Y), io:format(X, Y)).
-define(DEBUGF(X,Y), void).
+-type line() :: erl_scan:line(). % a convenient alias
+-type fa() :: {atom(), arity()}. % function+arity
+-type ta() :: {atom(), arity()}. % type+arity
+
%% Usage of records, functions, and imports. The variable table, which
%% is passed on as an argument, holds the usage of variables.
-record(usage, {
@@ -94,9 +98,11 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
mod_imports=dict:new() :: dict(), %Module Imports
compile=[], %Compile flags
records=dict:new() :: dict(), %Record definitions
+ locals=gb_sets:empty() :: gb_set(), %All defined functions (prescanned)
+ no_auto=gb_sets:empty() :: gb_set(), %Functions explicitly not autoimported
defined=gb_sets:empty() :: gb_set(), %Defined fuctions
- on_load=[] :: [{atom(),integer()}], %On-load function
- on_load_line=0 :: integer(), %Line for on_load
+ on_load=[] :: [fa()], %On-load function
+ on_load_line=0 :: line(), %Line for on_load
clashes=[], %Exported functions named as BIFs
not_deprecated=[], %Not considered deprecated
func=[], %Current function
@@ -110,10 +116,11 @@ value_option(Flag, Default, On, OnVal, Off, OffVal, Opts) ->
%outside any fun or lc
xqlc= false :: boolean(), %true if qlc.hrl included
new = false :: boolean(), %Has user-defined 'new/N'
- called= [], %Called functions
+ called= [] :: [{fa(),line()}], %Called functions
usage = #usage{} :: #usage{},
specs = dict:new() :: dict(), %Type specifications
- types = dict:new() :: dict() %Type definitions
+ types = dict:new() :: dict(), %Type definitions
+ exp_types=gb_sets:empty():: gb_set() %Exported types
}).
-type lint_state() :: #lint{}.
@@ -161,6 +168,9 @@ format_error({bad_nowarn_unused_function,{F,A}}) ->
io_lib:format("function ~w/~w undefined", [F,A]);
format_error({bad_nowarn_bif_clash,{F,A}}) ->
io_lib:format("function ~w/~w undefined", [F,A]);
+format_error(disallowed_nowarn_bif_clash) ->
+ io_lib:format("compile directive nowarn_bif_clash is no longer allowed,~n"
+ " - use explicit module names or -compile({no_auto_import, [F/A]})", []);
format_error({bad_nowarn_deprecated_function,{M,F,A}}) ->
io_lib:format("~w:~w/~w is not a deprecated function", [M,F,A]);
format_error({bad_on_load,Term}) ->
@@ -186,13 +196,21 @@ format_error({define_import,{F,A}}) ->
io_lib:format("defining imported function ~w/~w", [F,A]);
format_error({unused_function,{F,A}}) ->
io_lib:format("function ~w/~w is unused", [F,A]);
-format_error({redefine_bif,{F,A}}) ->
- io_lib:format("defining BIF ~w/~w", [F,A]);
format_error({call_to_redefined_bif,{F,A}}) ->
- io_lib:format("call to ~w/~w will call erlang:~w/~w; "
- "not ~w/~w in this module \n"
- " (add an explicit module name to the call to avoid this error)",
- [F,A,F,A,F,A]);
+ io_lib:format("ambiguous call of redefined auto-imported BIF ~w/~w~n"
+ " - use erlang:~w/~w or \"-compile({no_auto_import,[~w/~w]}).\" "
+ "to resolve name clash", [F,A,F,A,F,A]);
+format_error({call_to_redefined_old_bif,{F,A}}) ->
+ io_lib:format("ambiguous call of redefined pre R14 auto-imported BIF ~w/~w~n"
+ " - use erlang:~w/~w or \"-compile({no_auto_import,[~w/~w]}).\" "
+ "to resolve name clash", [F,A,F,A,F,A]);
+format_error({redefine_old_bif_import,{F,A}}) ->
+ io_lib:format("import directive redefines pre R14 auto-imported BIF ~w/~w~n"
+ " - use \"-compile({no_auto_import,[~w/~w]}).\" "
+ "to resolve name clash", [F,A,F,A]);
+format_error({redefine_bif_import,{F,A}}) ->
+ io_lib:format("import directive redefines auto-imported BIF ~w/~w~n"
+ " - use \"-compile({no_auto_import,[~w/~w]}).\" to resolve name clash", [F,A,F,A]);
format_error({deprecated, MFA, ReplacementMFA, Rel}) ->
io_lib:format("~s is deprecated and will be removed in ~s; use ~s",
@@ -242,10 +260,10 @@ format_error({untyped_record,T}) ->
format_error({unbound_var,V}) ->
io_lib:format("variable ~w is unbound", [V]);
format_error({unsafe_var,V,{What,Where}}) ->
- io_lib:format("variable ~w unsafe in ~w ~s",
+ io_lib:format("variable ~w unsafe in ~w ~s",
[V,What,format_where(Where)]);
format_error({exported_var,V,{What,Where}}) ->
- io_lib:format("variable ~w exported from ~w ~s",
+ io_lib:format("variable ~w exported from ~w ~s",
[V,What,format_where(Where)]);
format_error({shadowed_var,V,In}) ->
io_lib:format("variable ~w shadowed in ~w", [V,In]);
@@ -290,22 +308,24 @@ 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({duplicated_export_type, {T, A}}) ->
+ io_lib:format("type ~w/~w already exported", [T, A]);
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)]);
format_error({new_builtin_type, {TypeName, Arity}}) ->
io_lib:format("type ~w~s is a new builtin type; "
- "its (re)definition is allowed only until the next release",
+ "its (re)definition is allowed only until the next release",
[TypeName, gen_type_paren(Arity)]);
format_error({builtin_type, {TypeName, Arity}}) ->
- io_lib:format("type ~w~s is a builtin type; it cannot be redefined",
+ io_lib:format("type ~w~s is a builtin type; it cannot be redefined",
[TypeName, gen_type_paren(Arity)]);
format_error({renamed_type, OldName, NewName}) ->
io_lib:format("type ~w() is now called ~w(); "
"please use the new name instead", [OldName, NewName]);
format_error({redefine_type, {TypeName, Arity}}) ->
- io_lib:format("type ~w~s already defined",
+ io_lib:format("type ~w~s already defined",
[TypeName, gen_type_paren(Arity)]);
format_error({type_syntax, Constr}) ->
io_lib:format("bad ~w type", [Constr]);
@@ -354,7 +374,7 @@ pseudolocals() ->
%%
%% Used by erl_eval.erl to check commands.
-%%
+%%
exprs(Exprs, BindingsList) ->
exprs_opt(Exprs, BindingsList, []).
@@ -362,7 +382,7 @@ exprs_opt(Exprs, BindingsList, Opts) ->
{St0,Vs} = foldl(fun({{record,_SequenceNumber,_Name},Attr0}, {St1,Vs1}) ->
Attr = zip_file_and_line(Attr0, "none"),
{attribute_state(Attr, St1),Vs1};
- ({V,_}, {St1,Vs1}) ->
+ ({V,_}, {St1,Vs1}) ->
{St1,[{V,{bound,unused,[]}} | Vs1]}
end, {start("nofile",Opts),[]}, BindingsList),
Vt = orddict:from_list(Vs),
@@ -391,7 +411,7 @@ module(Forms) ->
Opts = compiler_options(Forms),
St = forms(Forms, start("nofile", Opts)),
return_status(St).
-
+
module(Forms, FileName) ->
Opts = compiler_options(Forms),
St = forms(Forms, start(FileName, Opts)),
@@ -506,7 +526,7 @@ pack_errors(Es) ->
%% Sort on line number.
pack_warnings(Ws) ->
- [{File,lists:sort([W || {F,W} <- Ws, F =:= File])} ||
+ [{File,lists:sort([W || {F,W} <- Ws, F =:= File])} ||
File <- lists:usort([F || {F,_} <- Ws])].
%% add_error(ErrorDescriptor, State) -> State'
@@ -516,13 +536,13 @@ pack_warnings(Ws) ->
add_error(E, St) -> St#lint{errors=[{St#lint.file,E}|St#lint.errors]}.
-add_error(FileLine, E, St) ->
+add_error(FileLine, E, St) ->
{File,Location} = loc(FileLine),
add_error({Location,erl_lint,E}, St#lint{file = File}).
add_warning(W, St) -> St#lint{warnings=[{St#lint.file,W}|St#lint.warnings]}.
-add_warning(FileLine, W, St) ->
+add_warning(FileLine, W, St) ->
{File,Location} = loc(FileLine),
add_warning({Location,erl_lint,W}, St#lint{file = File}).
@@ -538,8 +558,12 @@ loc(L) ->
forms(Forms0, St0) ->
Forms = eval_file_attribute(Forms0, St0),
+ Locals = local_functions(Forms),
+ AutoImportSuppressed = auto_import_suppressed(St0#lint.compile),
+ StDeprecated = disallowed_compile_flags(Forms,St0),
%% Line numbers are from now on pairs {File,Line}.
- St1 = includes_qlc_hrl(Forms, St0),
+ St1 = includes_qlc_hrl(Forms, StDeprecated#lint{locals = Locals,
+ no_auto = AutoImportSuppressed}),
St2 = bif_clashes(Forms, St1),
St3 = not_deprecated(Forms, St2),
St4 = foldl(fun form/2, pre_scan(Forms, St3), Forms),
@@ -561,7 +585,7 @@ pre_scan([_ | Fs], St) ->
pre_scan(Fs, St);
pre_scan([], St) ->
St.
-
+
includes_qlc_hrl(Forms, St) ->
%% QLC calls erl_lint several times, sometimes with the compile
%% attribute removed. The file attribute, however, is left as is.
@@ -667,6 +691,8 @@ attribute_state({attribute,L,extends,_M}, St) ->
add_error(L, invalid_extends, St);
attribute_state({attribute,L,export,Es}, St) ->
export(L, Es, St);
+attribute_state({attribute,L,export_type,Es}, St) ->
+ export_type(L, Es, St);
attribute_state({attribute,L,import,Is}, St) ->
import(L, Is, St);
attribute_state({attribute,L,record,{Name,Fields}}, St) ->
@@ -724,27 +750,38 @@ bif_clashes(Forms, St) ->
Clashes = ordsets:subtract(ordsets:from_list(Clashes0), Nowarn),
St#lint{clashes=Clashes}.
--spec is_bif_clash(atom(), byte(), lint_state()) -> boolean().
-
-is_bif_clash(_Name, _Arity, #lint{clashes=[]}) ->
- false;
-is_bif_clash(Name, Arity, #lint{clashes=Clashes}) ->
- ordsets:is_element({Name,Arity}, Clashes).
-
%% not_deprecated(Forms, State0) -> State
not_deprecated(Forms, St0) ->
%% There are no line numbers in St0#lint.compile.
- MFAsL = [{MFA,L} ||
+ MFAsL = [{MFA,L} ||
{attribute, L, compile, Args} <- Forms,
{nowarn_deprecated_function, MFAs0} <- lists:flatten([Args]),
MFA <- lists:flatten([MFAs0])],
Nowarn = [MFA || {MFA,_L} <- MFAsL],
- Bad = [MFAL || {{M,F,A},_L}=MFAL <- MFAsL,
+ Bad = [MFAL || {{M,F,A},_L}=MFAL <- MFAsL,
otp_internal:obsolete(M, F, A) =:= no],
St1 = func_line_warning(bad_nowarn_deprecated_function, Bad, St0),
St1#lint{not_deprecated = ordsets:from_list(Nowarn)}.
+%% The nowarn_bif_clash directive is not only deprecated, it's actually an error from R14A
+disallowed_compile_flags(Forms, St0) ->
+ %% There are (still) no line numbers in St0#lint.compile.
+ Errors0 = [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} ||
+ {attribute,[{line,{_,L}}],compile,nowarn_bif_clash} <- Forms ],
+ Errors1 = [ {St0#lint.file,{L,erl_lint,disallowed_nowarn_bif_clash}} ||
+ {attribute,[{line,{_,L}}],compile,{nowarn_bif_clash, {_,_}}} <- Forms ],
+ Disabled = (not is_warn_enabled(bif_clash, St0)),
+ Errors = if
+ Disabled andalso Errors0 =:= [] ->
+ [{St0#lint.file,{erl_lint,disallowed_nowarn_bif_clash}} | St0#lint.errors];
+ Disabled ->
+ Errors0 ++ Errors1 ++ St0#lint.errors;
+ true ->
+ Errors1 ++ St0#lint.errors
+ end,
+ St0#lint{errors=Errors}.
+
%% post_traversal_check(Forms, State0) -> State.
%% Do some further checking after the forms have been traversed and
%% data about calls etc. have been collected.
@@ -862,7 +899,7 @@ check_deprecated(Forms, St0) ->
Bad = [{E,L} || {attribute, L, deprecated, Depr} <- Forms,
D <- lists:flatten([Depr]),
E <- depr_cat(D, X, Mod)],
- foldl(fun ({E,L}, St1) ->
+ foldl(fun ({E,L}, St1) ->
add_error(L, E, St1)
end, St0, Bad).
@@ -912,7 +949,7 @@ check_imports(Forms, St0) ->
true ->
Usage = St0#lint.usage,
Unused = ordsets:subtract(St0#lint.imports, Usage#usage.imported),
- Imports = [{{FA,list_to_atom(package_to_string(Mod))},L}
+ Imports = [{{FA,list_to_atom(package_to_string(Mod))},L}
|| {attribute,L,import,{Mod,Fs}} <- Forms,
FA <- lists:usort(Fs)],
Bad = [{FM,L} || FM <- Unused, {FM2,L} <- Imports, FM =:= FM2],
@@ -932,7 +969,7 @@ check_unused_functions(Forms, St0) ->
Opts = St1#lint.compile,
case member(export_all, Opts) orelse
not is_warn_enabled(unused_function, St1) of
- true ->
+ true ->
St1;
false ->
Nowarn = nowarn_function(nowarn_unused_function, Opts),
@@ -1003,12 +1040,13 @@ check_option_functions(Forms, Tag0, Type, St0) ->
{Tag, FAs0} <- lists:flatten([Args]),
Tag0 =:= Tag,
FA <- lists:flatten([FAs0])],
- DefFunctions = gb_sets:to_list(St0#lint.defined) -- pseudolocals(),
+ DefFunctions = (gb_sets:to_list(St0#lint.defined) -- pseudolocals()) ++
+ [{F,A} || {{F,A},_} <- orddict:to_list(St0#lint.imports)],
Bad = [{FA,L} || {FA,L} <- FAsL, not member(FA, DefFunctions)],
func_line_error(Type, Bad, St0).
nowarn_function(Tag, Opts) ->
- ordsets:from_list([FA || {Tag1,FAs} <- Opts,
+ ordsets:from_list([FA || {Tag1,FAs} <- Opts,
Tag1 =:= Tag,
FA <- lists:flatten([FAs])]).
@@ -1048,10 +1086,10 @@ check_unused_records(Forms, St0) ->
%% functions count.
Usage = St0#lint.usage,
UsedRecords = sets:to_list(Usage#usage.used_records),
- URecs = foldl(fun (Used, Recs) ->
- dict:erase(Used, Recs)
+ URecs = foldl(fun (Used, Recs) ->
+ dict:erase(Used, Recs)
end, St0#lint.records, UsedRecords),
- Unused = [{Name,FileLine} ||
+ Unused = [{Name,FileLine} ||
{Name,{FileLine,_Fields}} <- dict:to_list(URecs),
element(1, loc(FileLine)) =:= FirstFile],
foldl(fun ({N,L}, St) ->
@@ -1061,18 +1099,19 @@ check_unused_records(Forms, St0) ->
St0
end.
-%% For storing the import list we use the orddict module.
+%% For storing the import list we use the orddict module.
%% We know an empty set is [].
-%% export(Line, Exports, State) -> State.
+-spec export(line(), [fa()], lint_state()) -> lint_state().
%% Mark functions as exported, also as called from the export line.
export(Line, Es, #lint{exports = Es0, called = Called} = St0) ->
- {Es1,C1,St1} =
+ {Es1,C1,St1} =
foldl(fun (NA, {E,C,St2}) ->
St = case gb_sets:is_element(NA, E) of
true ->
- add_warning(Line, {duplicated_export, NA}, St2);
+ Warn = {duplicated_export,NA},
+ add_warning(Line, Warn, St2);
false ->
St2
end,
@@ -1081,8 +1120,27 @@ export(Line, Es, #lint{exports = Es0, called = Called} = St0) ->
{Es0,Called,St0}, Es),
St1#lint{exports = Es1, called = C1}.
-%% import(Line, Imports, State) -> State.
-%% imported(Name, Arity, State) -> {yes,Module} | no.
+-spec export_type(line(), [ta()], lint_state()) -> lint_state().
+%% Mark types as exported; also mark them as used from the export line.
+
+export_type(Line, ETs, #lint{usage = Usage, exp_types = ETs0} = St0) ->
+ UTs0 = Usage#usage.used_types,
+ {ETs1,UTs1,St1} =
+ foldl(fun (TA, {E,U,St2}) ->
+ St = case gb_sets:is_element(TA, E) of
+ true ->
+ Warn = {duplicated_export_type,TA},
+ add_warning(Line, Warn, St2);
+ false ->
+ St2
+ end,
+ {gb_sets:add_element(TA, E), dict:store(TA, Line, U), St}
+ end,
+ {ETs0,UTs0,St0}, ETs),
+ St1#lint{usage = Usage#usage{used_types = UTs1}, exp_types = ETs1}.
+
+-type import() :: {module(), [fa()]} | module().
+-spec import(line(), import(), lint_state()) -> lint_state().
import(Line, {Mod,Fs}, St) ->
Mod1 = package_to_string(Mod),
@@ -1094,11 +1152,41 @@ import(Line, {Mod,Fs}, St) ->
St#lint{imports=add_imports(list_to_atom(Mod1), Mfs,
St#lint.imports)};
Efs ->
- foldl(fun (Ef, St0) ->
- add_error(Line, {redefine_import,Ef},
- St0)
+ {Err, St1} =
+ foldl(fun ({bif,{F,A},_}, {Err,St0}) ->
+ %% BifClash - import directive
+ Warn = is_warn_enabled(bif_clash, St0)
+ and (not bif_clash_specifically_disabled(St0,{F,A})),
+ AutoImpSup = is_autoimport_suppressed(St0#lint.no_auto,{F,A}),
+ OldBif = erl_internal:old_bif(F,A),
+ {Err,if
+ Warn and (not AutoImpSup) and OldBif ->
+ add_error
+ (Line,
+ {redefine_old_bif_import, {F,A}},
+ St0);
+ Warn and (not AutoImpSup) ->
+ add_warning
+ (Line,
+ {redefine_bif_import, {F,A}},
+ St0);
+ true ->
+ St0
+ end};
+ (Ef, {_Err,St0}) ->
+ {true,add_error(Line,
+ {redefine_import,Ef},
+ St0)}
end,
- St, Efs)
+ {false,St}, Efs),
+ if
+ not Err ->
+ St1#lint{imports=
+ add_imports(list_to_atom(Mod1), Mfs,
+ St#lint.imports)};
+ true ->
+ St1
+ end
end;
false ->
add_error(Line, {bad_module_name, Mod1}, St)
@@ -1141,13 +1229,15 @@ check_imports(_Line, Fs, Is) ->
add_imports(Mod, Fs, Is) ->
foldl(fun (F, Is0) -> orddict:store(F, Mod, Is0) end, Is, Fs).
+-spec imported(atom(), arity(), lint_state()) -> {'yes',module()} | 'no'.
+
imported(F, A, St) ->
case orddict:find({F,A}, St#lint.imports) of
{ok,Mod} -> {yes,Mod};
error -> no
end.
-%% on_load(Line, Val, State) -> State.
+-spec on_load(line(), fa(), lint_state()) -> lint_state().
%% Check an on_load directive and remember it.
on_load(Line, {Name,Arity}=Fa, #lint{on_load=OnLoad0}=St0)
@@ -1179,7 +1269,7 @@ check_on_load(#lint{defined=Defined,on_load=[{_,0}=Fa],
end;
check_on_load(St) -> St.
-%% call_function(Line, Name, Arity, State) -> State.
+-spec call_function(line(), atom(), arity(), lint_state()) -> lint_state().
%% Add to both called and calls.
call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func}=St) ->
@@ -1191,12 +1281,6 @@ call_function(Line, F, A, #lint{usage=Usage0,called=Cd,func=Func}=St) ->
end,
St#lint{called=[{NA,Line}|Cd], usage=Usage}.
-%% is_function_exported(Name, Arity, State) -> false|true.
-
-is_function_exported(Name, Arity, #lint{exports=Exports,compile=Compile}) ->
- gb_sets:is_element({Name,Arity}, Exports) orelse
- member(export_all, Compile).
-
%% function(Line, Name, Arity, Clauses, State) -> State.
function(Line, instance, _Arity, _Cs, St) when St#lint.global_vt =/= [] ->
@@ -1205,7 +1289,7 @@ function(Line, Name, Arity, Cs, St0) ->
St1 = define_function(Line, Name, Arity, St0#lint{func={Name,Arity}}),
clauses(Cs, St1#lint.global_vt, St1).
-%% define_function(Line, Name, Arity, State) -> State.
+-spec define_function(line(), atom(), arity(), lint_state()) -> lint_state().
define_function(Line, Name, Arity, St0) ->
St1 = keyword_warning(Line, Name, St0),
@@ -1215,14 +1299,9 @@ define_function(Line, Name, Arity, St0) ->
add_error(Line, {redefine_function,NA}, St1);
false ->
St2 = St1#lint{defined=gb_sets:add_element(NA, St1#lint.defined)},
- St = case erl_internal:bif(Name, Arity) andalso
- not is_function_exported(Name, Arity, St2) of
- true -> add_warning(Line, {redefine_bif,NA}, St2);
- false -> St2
- end,
- case imported(Name, Arity, St) of
- {yes,_M} -> add_error(Line, {define_import,NA}, St);
- no -> St
+ case imported(Name, Arity, St2) of
+ {yes,_M} -> add_error(Line, {define_import,NA}, St2);
+ no -> St2
end
end.
@@ -1258,7 +1337,7 @@ head([P|Ps], Vt, Old, St0) ->
{vtmerge_pat(Pvt, Psvt),vtmerge_pat(Bvt1,Bvt2),St2};
head([], _Vt, _Env, St) -> {[],[],St}.
-%% pattern(Pattern, VarTable, Old, BinVarTable, State) ->
+%% pattern(Pattern, VarTable, Old, BinVarTable, State) ->
%% {UpdVarTable,BinVarTable,State}.
%% Check pattern return variables. Old is the set of variables used for
%% deciding whether an occurrence is a binding occurrence or a use, and
@@ -1276,7 +1355,7 @@ pattern(P, Vt, St) ->
pattern({var,_Line,'_'}, _Vt, _Old, _Bvt, St) ->
{[],[],St}; %Ignore anonymous variable
-pattern({var,Line,V}, _Vt, Old, Bvt, St) ->
+pattern({var,Line,V}, _Vt, Old, Bvt, St) ->
pat_var(V, Line, Old, Bvt, St);
pattern({char,_Line,_C}, _Vt, _Old, _Bvt, St) -> {[],[],St};
pattern({integer,_Line,_I}, _Vt, _Old, _Bvt, St) -> {[],[],St};
@@ -1294,7 +1373,7 @@ pattern({tuple,_Line,Ps}, Vt, Old, Bvt, St) ->
%%pattern({struct,_Line,_Tag,Ps}, Vt, Old, Bvt, St) ->
%% pattern_list(Ps, Vt, Old, Bvt, St);
pattern({record_index,Line,Name,Field}, _Vt, _Old, _Bvt, St) ->
- {Vt1,St1} =
+ {Vt1,St1} =
check_record(Line, Name, St,
fun (Dfs, St1) ->
pattern_field(Field, Name, Dfs, St1)
@@ -1309,7 +1388,7 @@ pattern({record_field,Line,_,_}=M, _Vt, _Old, _Bvt, St0) ->
end;
pattern({record,Line,Name,Pfs}, Vt, Old, Bvt, St) ->
case dict:find(Name, St#lint.records) of
- {ok,{_Line,Fields}} ->
+ {ok,{_Line,Fields}} ->
St1 = used_record(Name, St),
pattern_fields(Pfs, Name, Fields, Vt, Old, Bvt, St1);
error -> {[],[],add_error(Line, {undefined_record,Name}, St)}
@@ -1369,7 +1448,7 @@ reject_bin_alias({cons,_,H1,T1}, {cons,_,H2,T2}, St0) ->
reject_bin_alias(T1, T2, St);
reject_bin_alias({tuple,_,Es1}, {tuple,_,Es2}, St) ->
reject_bin_alias_list(Es1, Es2, St);
-reject_bin_alias({record,_,Name1,Pfs1}, {record,_,Name2,Pfs2},
+reject_bin_alias({record,_,Name1,Pfs1}, {record,_,Name2,Pfs2},
#lint{records=Recs}=St) ->
case {dict:find(Name1, Recs),dict:find(Name2, Recs)} of
{{ok,{_Line1,Fields1}},{ok,{_Line2,Fields2}}} ->
@@ -1451,7 +1530,7 @@ is_pattern_expr_1({op,_Line,Op,A1,A2}) ->
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) ->
+%% pattern_bin([Element], VarTable, Old, BinVarTable, State) ->
%% {UpdVarTable,UpdBinVarTable,State}.
%% Check a pattern group. BinVarTable are used binsize variables.
@@ -1498,7 +1577,7 @@ good_string_size_type(default, Ts) ->
end, Ts);
good_string_size_type(_, _) -> false.
-%% pat_bit_expr(Pattern, OldVarTable, BinVarTable,State) ->
+%% pat_bit_expr(Pattern, OldVarTable, BinVarTable,State) ->
%% {UpdVarTable,UpdBinVarTable,State}.
%% Check pattern bit expression, only allow really valid patterns!
@@ -1513,7 +1592,7 @@ pat_bit_expr(P, _Old, _Bvt, St) ->
false -> {[],[],add_error(element(2, P), illegal_pattern, St)}
end.
-%% pat_bit_size(Size, VarTable, BinVarTable, State) ->
+%% pat_bit_size(Size, VarTable, BinVarTable, State) ->
%% {Value,UpdVarTable,UpdBinVarTable,State}.
%% Check pattern size expression, only allow really valid sizes!
@@ -1596,7 +1675,7 @@ bit_size_check(Line, Size, #bittype{type=Type,unit=Unit}, St) ->
Sz = Unit * Size, %Total number of bits!
St2 = elemtype_check(Line, Type, Sz, St),
{Sz,St2}.
-
+
elemtype_check(_Line, float, 32, St) -> St;
elemtype_check(_Line, float, 64, St) -> St;
elemtype_check(Line, float, _Size, St) ->
@@ -1678,8 +1757,6 @@ gexpr({cons,_Line,H,T}, Vt, St) ->
gexpr_list([H,T], Vt, St);
gexpr({tuple,_Line,Es}, Vt, St) ->
gexpr_list(Es, Vt, St);
-%%gexpr({struct,_Line,_Tag,Es}, Vt, St) ->
-%% gexpr_list(Es, Vt, St);
gexpr({record_index,Line,Name,Field}, _Vt, St) ->
check_record(Line, Name, St,
fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end );
@@ -1710,7 +1787,7 @@ gexpr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) ->
gexpr({call,Line,{atom,_Lr,is_record},[E,R]}, Vt, St0) ->
{Asvt,St1} = gexpr_list([E,R], Vt, St0),
{Asvt,add_error(Line, illegal_guard_expr, St1)};
-gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]},
+gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]},
Vt, St0) ->
gexpr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0);
gexpr({call,_Line,{atom,_Lr,is_record},[E,{atom,_,_Name},{integer,_,_}]},
@@ -1725,14 +1802,16 @@ gexpr({call,Line,{remote,_,{atom,_,erlang},{atom,_,is_record}=Isr},[_,_,_]=Args}
gexpr({call,Line,{atom,_La,F},As}, Vt, St0) ->
{Asvt,St1} = gexpr_list(As, Vt, St0),
A = length(As),
- case erl_internal:guard_bif(F, A) of
+ %% BifClash - Function called in guard
+ case erl_internal:guard_bif(F, A) andalso no_guard_bif_clash(St1,{F,A}) of
true ->
%% Also check that it is auto-imported.
case erl_internal:bif(F, A) of
true -> {Asvt,St1};
false -> {Asvt,add_error(Line, {explicit_export,F,A}, St1)}
end;
- false -> {Asvt,add_error(Line, illegal_guard_expr, St1)}
+ false ->
+ {Asvt,add_error(Line, illegal_guard_expr, St1)}
end;
gexpr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,_Lf,F}},As}, Vt, St0) ->
{Asvt,St1} = gexpr_list(As, Vt, St0),
@@ -1777,7 +1856,7 @@ is_guard_test(E) ->
%% is_guard_test(Expression, Forms) -> boolean().
is_guard_test(Expression, Forms) ->
RecordAttributes = [A || A = {attribute, _, record, _D} <- Forms],
- St0 = foldl(fun(Attr0, St1) ->
+ St0 = foldl(fun(Attr0, St1) ->
Attr = zip_file_and_line(Attr0, "none"),
attribute_state(Attr, St1)
end, start(), RecordAttributes),
@@ -1798,7 +1877,7 @@ is_guard_test2(G, RDs) ->
%% is_guard_expr(Expression) -> boolean().
%% Test if an expression is a guard expression.
-is_guard_expr(E) -> is_gexpr(E, []).
+is_guard_expr(E) -> is_gexpr(E, []).
is_gexpr({var,_L,_V}, _RDs) -> true;
is_gexpr({char,_L,_C}, _RDs) -> true;
@@ -1820,7 +1899,7 @@ is_gexpr({record_field,_L,Rec,_Name,Field}, RDs) ->
is_gexpr({record,L,Name,Inits}, RDs) ->
is_gexpr_fields(Inits, L, Name, RDs);
is_gexpr({bin,_L,Fs}, RDs) ->
- all(fun ({bin_element,_Line,E,Sz,_Ts}) ->
+ all(fun ({bin_element,_Line,E,Sz,_Ts}) ->
is_gexpr(E, RDs) and (Sz =:= default orelse is_gexpr(Sz, RDs))
end, Fs);
is_gexpr({call,_L,{atom,_Lf,F},As}, RDs) ->
@@ -1895,15 +1974,13 @@ expr({bc,_Line,E,Qs}, Vt0, St0) ->
{vtold(Vt,Vt0),St}; %Don't export local variables
expr({tuple,_Line,Es}, Vt, St) ->
expr_list(Es, Vt, St);
-%%expr({struct,Line,Tag,Es}, Vt, St) ->
-%% expr_list(Es, Vt, St);
expr({record_index,Line,Name,Field}, _Vt, St) ->
check_record(Line, Name, St,
fun (Dfs, St1) -> record_field(Field, Name, Dfs, St1) end);
expr({record,Line,Name,Inits}, Vt, St) ->
check_record(Line, Name, St,
- fun (Dfs, St1) ->
- init_fields(Inits, Line, Name, Dfs, Vt, St1)
+ fun (Dfs, St1) ->
+ init_fields(Inits, Line, Name, Dfs, Vt, St1)
end);
expr({record_field,Line,_,_}=M, _Vt, St0) ->
case expand_package(M, St0) of
@@ -1958,8 +2035,11 @@ expr({'fun',Line,Body}, Vt, St) ->
{Bvt, St1} = fun_clauses(Cs, Vt, St),
{vtupdate(Bvt, Vt), St1};
{function,F,A} ->
+ %% BifClash - Fun expression
%% N.B. Only allows BIFs here as well, NO IMPORTS!!
- case erl_internal:bif(F, A) of
+ case ((not is_local_function(St#lint.locals,{F,A})) andalso
+ (erl_internal:bif(F, A) andalso
+ (not is_autoimport_suppressed(St#lint.no_auto,{F,A})))) of
true -> {[],St};
false -> {[],call_function(Line, F, A, St)}
end;
@@ -1969,7 +2049,7 @@ expr({'fun',Line,Body}, Vt, St) ->
expr({call,_Line,{atom,_Lr,is_record},[E,{atom,Ln,Name}]}, Vt, St0) ->
{Rvt,St1} = expr(E, Vt, St0),
{Rvt,exist_record(Ln, Name, St1)};
-expr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]},
+expr({call,Line,{remote,_Lr,{atom,_Lm,erlang},{atom,Lf,is_record}},[E,A]},
Vt, St0) ->
expr({call,Line,{atom,Lf,is_record},[E,A]}, Vt, St0);
expr({call,L,{tuple,Lt,[{atom,Lm,erlang},{atom,Lf,is_record}]},As}, Vt, St) ->
@@ -1992,16 +2072,14 @@ expr({call,Line,{atom,La,F},As}, Vt, St0) ->
St1 = keyword_warning(La, F, St0),
{Asvt,St2} = expr_list(As, Vt, St1),
A = length(As),
- case erl_internal:bif(F, A) of
+ IsLocal = is_local_function(St2#lint.locals,{F,A}),
+ IsAutoBif = erl_internal:bif(F, A),
+ AutoSuppressed = is_autoimport_suppressed(St2#lint.no_auto,{F,A}),
+ Warn = is_warn_enabled(bif_clash, St2) and (not bif_clash_specifically_disabled(St2,{F,A})),
+ case ((not IsLocal) andalso IsAutoBif andalso (not AutoSuppressed)) of
true ->
St3 = deprecated_function(Line, erlang, F, As, St2),
- {Asvt,case is_warn_enabled(bif_clash, St3) andalso
- is_bif_clash(F, A, St3) of
- false ->
- St3;
- true ->
- add_error(Line, {call_to_redefined_bif,{F,A}}, St3)
- end};
+ {Asvt,St3};
false ->
{Asvt,case imported(F, A, St2) of
{yes,M} ->
@@ -2010,11 +2088,36 @@ expr({call,Line,{atom,La,F},As}, Vt, St0) ->
Imp = ordsets:add_element({{F,A},M},U0#usage.imported),
St3#lint{usage=U0#usage{imported = Imp}};
no ->
- case {F,A} of
- {record_info,2} ->
+ case {F,A} of
+ {record_info,2} ->
check_record_info_call(Line,La,As,St2);
- N when N =:= St2#lint.func -> St2;
- _ -> call_function(Line, F, A, St2)
+ N ->
+ %% BifClash - function call
+ %% Issue these warnings/errors even if it's a recursive call
+ St3 = if
+ (not AutoSuppressed) andalso IsAutoBif andalso Warn ->
+ case erl_internal:old_bif(F,A) of
+ true ->
+ add_error
+ (Line,
+ {call_to_redefined_old_bif, {F,A}},
+ St2);
+ false ->
+ add_warning
+ (Line,
+ {call_to_redefined_bif, {F,A}},
+ St2)
+ end;
+ true ->
+ St2
+ end,
+ %% ...but don't lint recursive calls
+ if
+ N =:= St3#lint.func ->
+ St3;
+ true ->
+ call_function(Line, F, A, St3)
+ end
end
end}
end;
@@ -2155,7 +2258,7 @@ def_fields(Fs0, Name, St0) ->
foldl(fun ({record_field,Lf,{atom,La,F},V}, {Fs,St}) ->
case exist_field(F, Fs) of
true -> {Fs,add_error(Lf, {redefine_field,Name,F}, St)};
- false ->
+ false ->
St1 = St#lint{recdef_top = true},
{_,St2} = expr(V, [], St1),
%% Warnings and errors found are kept, but
@@ -2306,7 +2409,7 @@ init_fields(Ifs, Line, Name, Dfs, Vt0, St0) ->
Defs = init_fields(Ifs, Line, Dfs),
{_,St2} = check_fields(Defs, Name, Dfs, Vt1, St1, fun expr/3),
{Vt1,St1#lint{usage = St2#lint.usage}}.
-
+
ginit_fields(Ifs, Line, Name, Dfs, Vt0, St0) ->
{Vt1,St1} = check_fields(Ifs, Name, Dfs, Vt0, St0, fun gexpr/3),
Defs = init_fields(Ifs, Line, Dfs),
@@ -2316,7 +2419,7 @@ ginit_fields(Ifs, Line, Name, Dfs, Vt0, St0) ->
IllErrs = [E || {_File,{_Line,erl_lint,illegal_guard_expr}}=E <- Errors],
St4 = St1#lint{usage = Usage, errors = IllErrs ++ St1#lint.errors},
{Vt1,St4}.
-
+
%% Default initializations to be carried out
init_fields(Ifs, Line, Dfs) ->
[ {record_field,Lf,{atom,La,F},copy_expr(Di, Line)} ||
@@ -2394,7 +2497,7 @@ check_type({ann_type, _L, [_Var, Type]}, SeenVars, St) ->
check_type(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]},
+check_type({remote_type, L, [{atom, _, Mod}, {atom, _, Name}, Args]},
SeenVars, #lint{module=CurrentMod} = St) ->
St1 =
case (dict:is_key({Name, length(Args)}, default_types())
@@ -2432,7 +2535,7 @@ check_type({type, L, 'fun', [Dom, Range]}, SeenVars, St) ->
check_type({type, -1, product, [Dom, Range]}, SeenVars, St1);
check_type({type, L, range, [From, To]}, SeenVars, St) ->
St1 =
- case {From, To} of
+ case {erl_eval:partial_eval(From), erl_eval:partial_eval(To)} of
{{integer, _, X}, {integer, _, Y}} when X < Y -> St;
_ -> add_error(L, {type_syntax, range}, St)
end,
@@ -2441,8 +2544,8 @@ check_type({type, _L, tuple, any}, SeenVars, St) -> {SeenVars, St};
check_type({type, _L, any}, SeenVars, St) -> {SeenVars, St};
check_type({type, L, binary, [Base, Unit]}, SeenVars, St) ->
St1 =
- case {Base, Unit} of
- {{integer, _, BaseVal},
+ case {erl_eval:partial_eval(Base), erl_eval:partial_eval(Unit)} of
+ {{integer, _, BaseVal},
{integer, _, UnitVal}} when BaseVal >= 0, UnitVal >= 0 -> St;
_ -> add_error(L, {type_syntax, binary}, St)
end,
@@ -2467,7 +2570,13 @@ check_type({type, La, TypeName, Args}, SeenVars, #lint{usage=Usage} = St) ->
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_type({type, -1, product, Args}, SeenVars, St1);
+check_type(I, SeenVars, St) ->
+ case erl_eval:partial_eval(I) of
+ {integer,_ILn,_Integer} -> {SeenVars, St};
+ _Other ->
+ {SeenVars, add_error(element(2, I), {type_syntax, integer}, St)}
+ end.
check_record_types(Line, Name, Fields, SeenVars, St) ->
case dict:find(Name, St#lint.records) of
@@ -2475,12 +2584,12 @@ check_record_types(Line, Name, Fields, SeenVars, St) ->
case lists:all(fun({type, _, field_type, _}) -> true;
(_) -> false
end, Fields) of
- true ->
+ true ->
check_record_types(Fields, Name, DefFields, SeenVars, St, []);
false ->
{SeenVars, add_error(Line, {type_syntax, record}, St)}
end;
- error ->
+ error ->
{SeenVars, add_error(Line, {undefined_record, Name}, St)}
end.
@@ -2606,7 +2715,7 @@ spec_decl(Line, MFA0, TypeSpecs, St0 = #lint{specs = Specs, module = Mod}) ->
check_specs([FunType|Left], Arity, St0) ->
{FunType1, CTypes} =
case FunType of
- {type, _, bounded_fun, [FT = {type, _, 'fun', _}, Cs]} ->
+ {type, _, bounded_fun, [FT = {type, _, 'fun', _}, Cs]} ->
Types0 = [T || {type, _, constraint, [_, T]} <- Cs],
{FT, lists:append(Types0)};
{type, _, 'fun', _} = FT -> {FT, []}
@@ -2666,10 +2775,12 @@ add_missing_spec_warnings(Forms, St0, Type) ->
add_warning(L, {missing_spec,FA}, St)
end, St0, Warns).
-check_unused_types(Forms, St = #lint{usage=Usage, types=Types}) ->
+check_unused_types(Forms, #lint{usage=Usage, types=Ts, exp_types=ExpTs}=St) ->
case [File || {attribute,_L,file,{File,_Line}} <- Forms] of
[FirstFile|_] ->
- UsedTypes = Usage#usage.used_types,
+ D = Usage#usage.used_types,
+ L = gb_sets:to_list(ExpTs) ++ dict:fetch_keys(D),
+ UsedTypes = gb_sets:from_list(L),
FoldFun =
fun(_Type, -1, AccSt) ->
%% Default type
@@ -2677,19 +2788,18 @@ check_unused_types(Forms, St = #lint{usage=Usage, types=Types}) ->
(Type, FileLine, AccSt) ->
case loc(FileLine) of
{FirstFile, _} ->
- case dict:is_key(Type, UsedTypes) of
+ case gb_sets:is_member(Type, UsedTypes) of
true -> AccSt;
- false ->
- add_warning(FileLine,
- {unused_type, Type},
- AccSt)
+ false ->
+ Warn = {unused_type,Type},
+ add_warning(FileLine, Warn, AccSt)
end;
_ ->
- %% Don't warn about unused types in include file
+ %% No warns about unused types in include files
AccSt
end
end,
- dict:fold(FoldFun, St, Types);
+ dict:fold(FoldFun, St, Ts);
[] ->
St
end.
@@ -2834,7 +2944,7 @@ fun_clause({clause,_Line,H,G,B}, Vt0, St0) ->
%%
%% used variable has been used
%% unused variable has been bound but not used
-%%
+%%
%% Lines is a list of line numbers where the variable was bound.
%%
%% Report variable errors/warnings as soon as possible and then change
@@ -2864,9 +2974,9 @@ pat_var(V, Line, Vt, Bvt, St) ->
case orddict:find(V, Bvt) of
{ok, {bound,_Usage,Ls}} ->
{[],[{V,{bound,used,Ls}}],St};
- error ->
+ error ->
case orddict:find(V, Vt) of
- {ok,{bound,_Usage,Ls}} ->
+ {ok,{bound,_Usage,Ls}} ->
{[{V,{bound,used,Ls}}],[],St};
{ok,{{unsafe,In},_Usage,Ls}} ->
{[{V,{bound,used,Ls}}],[],
@@ -2919,7 +3029,7 @@ pat_binsize_var(V, Line, Vt, Bvt, St) ->
expr_var(V, Line, Vt, St0) ->
case orddict:find(V, Vt) of
- {ok,{bound,_Usage,Ls}} ->
+ {ok,{bound,_Usage,Ls}} ->
{[{V,{bound,used,Ls}}],St0};
{ok,{{unsafe,In},_Usage,Ls}} ->
{[{V,{bound,used,Ls}}],
@@ -2957,7 +3067,7 @@ check_old_unused_vars(Vt, Vt0, St0) ->
warn_unused_vars(U, Vt, St0).
unused_vars(Vt, Vt0, _St0) ->
- U0 = orddict:filter(fun (V, {_State,unused,_Ls}) ->
+ U0 = orddict:filter(fun (V, {_State,unused,_Ls}) ->
case atom_to_list(V) of
"_"++_ -> false;
_ -> true
@@ -2973,7 +3083,7 @@ warn_unused_vars(U, Vt, St0) ->
false -> St0;
true ->
foldl(fun ({V,{_,unused,Ls}}, St) ->
- foldl(fun (L, St2) ->
+ foldl(fun (L, St2) ->
add_warning(L, {unused_var,V},
St2)
end, St, Ls)
@@ -3073,7 +3183,7 @@ vt_no_unsafe(Vt) -> [V || {_,{S,_U,_L}}=V <- Vt,
-ifdef(NOTUSED).
vunion(Vs1, Vs2) -> ordsets:union(vtnames(Vs1), vtnames(Vs2)).
-vunion(Vss) -> foldl(fun (Vs, Uvs) ->
+vunion(Vss) -> foldl(fun (Vs, Uvs) ->
ordsets:union(vtnames(Vs), Uvs)
end, [], Vss).
@@ -3103,7 +3213,7 @@ modify_line(T, F0) ->
%% Forms.
modify_line1({function,F,A}, _Mf) -> {function,F,A};
modify_line1({function,M,F,A}, _Mf) -> {function,M,F,A};
-modify_line1({attribute,L,record,{Name,Fields}}, Mf) ->
+modify_line1({attribute,L,record,{Name,Fields}}, Mf) ->
{attribute,Mf(L),record,{Name,modify_line1(Fields, Mf)}};
modify_line1({attribute,L,spec,{Fun,Types}}, Mf) ->
{attribute,Mf(L),spec,{Fun,modify_line1(Types, Mf)}};
@@ -3118,7 +3228,7 @@ modify_line1({warning,W}, _Mf) -> {warning,W};
modify_line1({error,W}, _Mf) -> {error,W};
%% Expressions.
modify_line1({clauses,Cs}, Mf) -> {clauses,modify_line1(Cs, Mf)};
-modify_line1({typed_record_field,Field,Type}, Mf) ->
+modify_line1({typed_record_field,Field,Type}, Mf) ->
{typed_record_field,modify_line1(Field, Mf),modify_line1(Type, Mf)};
modify_line1({Tag,L}, Mf) -> {Tag,Mf(L)};
modify_line1({Tag,L,E1}, Mf) ->
@@ -3154,7 +3264,7 @@ check_record_info_call(Line,_La,_As,St) ->
has_wildcard_field([{record_field,_Lf,{var,_La,'_'},_Val}|_Fs]) -> true;
has_wildcard_field([_|Fs]) -> has_wildcard_field(Fs);
has_wildcard_field([]) -> false.
-
+
%% check_remote_function(Line, ModuleName, FuncName, [Arg], State) -> State.
%% Perform checks on known remote calls.
@@ -3170,7 +3280,7 @@ check_remote_function(Line, M, F, As, St0) ->
check_qlc_hrl(Line, M, F, As, St) ->
Arity = length(As),
case As of
- [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q,
+ [{lc,_L,_E,_Qs}|_] when M =:= qlc, F =:= q,
Arity < 3, not St#lint.xqlc ->
add_warning(Line, {missing_qlc_hrl, Arity}, St);
_ ->
@@ -3355,11 +3465,11 @@ extract_sequence(3, [$.,_|Fmt], Need) ->
extract_sequence(4, Fmt, Need);
extract_sequence(3, Fmt, Need) ->
extract_sequence(4, Fmt, Need);
-extract_sequence(4, [$t, $c | Fmt], Need) ->
- extract_sequence(5, [$c|Fmt], Need);
-extract_sequence(4, [$t, $s | Fmt], Need) ->
- extract_sequence(5, [$s|Fmt], Need);
-extract_sequence(4, [$t, C | _Fmt], _Need) ->
+extract_sequence(4, [$t, $c | Fmt], Need) ->
+ extract_sequence(5, [$c|Fmt], Need);
+extract_sequence(4, [$t, $s | Fmt], Need) ->
+ extract_sequence(5, [$s|Fmt], Need);
+extract_sequence(4, [$t, C | _Fmt], _Need) ->
{error,"invalid control ~t" ++ [C]};
extract_sequence(4, Fmt, Need) ->
extract_sequence(5, Fmt, Need);
@@ -3437,3 +3547,56 @@ expand_package(M, St0) ->
{error, St1}
end
end.
+
+
+%% Prebuild set of local functions (to override auto-import)
+local_functions(Forms) ->
+ gb_sets:from_list([ {Func,Arity} || {function,_,Func,Arity,_} <- Forms ]).
+%% Predicate to find out if the function is locally defined
+is_local_function(LocalSet,{Func,Arity}) ->
+ gb_sets:is_element({Func,Arity},LocalSet).
+%% Predicate to see if a function is explicitly imported
+is_imported_function(ImportSet,{Func,Arity}) ->
+ case orddict:find({Func,Arity}, ImportSet) of
+ {ok,_Mod} -> true;
+ error -> false
+ end.
+%% Predicate to see if a function is explicitly imported from the erlang module
+is_imported_from_erlang(ImportSet,{Func,Arity}) ->
+ case orddict:find({Func,Arity}, ImportSet) of
+ {ok,erlang} -> true;
+ _ -> false
+ end.
+%% Build set of functions where auto-import is explicitly supressed
+auto_import_suppressed(CompileFlags) ->
+ L0 = [ X || {no_auto_import,X} <- CompileFlags ],
+ L1 = [ {Y,Z} || {Y,Z} <- lists:flatten(L0), is_atom(Y), is_integer(Z) ],
+ gb_sets:from_list(L1).
+%% Predicate to find out if autoimport is explicitly supressed for a function
+is_autoimport_suppressed(NoAutoSet,{Func,Arity}) ->
+ gb_sets:is_element({Func,Arity},NoAutoSet).
+%% Predicate to find out if a function specific bif-clash supression (old deprecated) is present
+bif_clash_specifically_disabled(St,{F,A}) ->
+ Nowarn = nowarn_function(nowarn_bif_clash, St#lint.compile),
+ lists:member({F,A},Nowarn).
+
+%% Predicate to find out if an autoimported guard_bif is not overriden in some way
+%% Guard Bif without module name is disallowed if
+%% * It is overridden by local function
+%% * It is overridden by -import and that import is not of itself (i.e. from module erlang)
+%% * The autoimport is suppressed or it's not reimported by -import directive
+%% Otherwise it's OK (given that it's actually a guard bif and actually is autoimported)
+no_guard_bif_clash(St,{F,A}) ->
+ (
+ (not is_local_function(St#lint.locals,{F,A}))
+ andalso
+ (
+ (not is_imported_function(St#lint.imports,{F,A})) orelse
+ is_imported_from_erlang(St#lint.imports,{F,A})
+ )
+ andalso
+ (
+ (not is_autoimport_suppressed(St#lint.no_auto, {F,A})) orelse
+ is_imported_from_erlang(St#lint.imports,{F,A})
+ )
+ ).
diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl
index 69807aad83..bb4b18cf9b 100644
--- a/lib/stdlib/src/erl_parse.yrl
+++ b/lib/stdlib/src/erl_parse.yrl
@@ -47,7 +47,7 @@ opt_bit_size_expr bit_size_expr opt_bit_type_list bit_type_list bit_type
top_type top_type_100 top_types type typed_expr typed_attr_val
type_sig type_sigs type_guard type_guards fun_type fun_type_100 binary_type
type_spec spec_fun typed_exprs typed_record_fields field_types field_type
-bin_base_type bin_unit_type int_type.
+bin_base_type bin_unit_type type_200 type_300 type_400 type_500.
Terminals
char integer float atom string var
@@ -61,7 +61,7 @@ char integer float atom string var
'++' '--'
'==' '/=' '=<' '<' '>=' '>' '=:=' '=/=' '<='
'<<' '>>'
-'!' '=' '::'
+'!' '=' '::' '..' '...'
'spec' % helper
dot.
@@ -112,6 +112,7 @@ type_guards -> type_guard ',' type_guards : ['$1'|'$3'].
type_guard -> atom '(' top_types ')' : {type, ?line('$1'), constraint,
['$1', '$3']}.
+type_guard -> var '::' top_type : build_def('$1', '$3').
top_types -> top_type : ['$1'].
top_types -> top_type ',' top_types : ['$1'|'$3'].
@@ -119,8 +120,24 @@ top_types -> top_type ',' top_types : ['$1'|'$3'].
top_type -> var '::' top_type_100 : {ann_type, ?line('$1'), ['$1','$3']}.
top_type -> top_type_100 : '$1'.
-top_type_100 -> type : '$1'.
-top_type_100 -> type '|' top_type_100 : lift_unions('$1','$3').
+top_type_100 -> type_200 : '$1'.
+top_type_100 -> type_200 '|' top_type_100 : lift_unions('$1','$3').
+
+type_200 -> type_300 '..' type_300 : {type, ?line('$1'), range,
+ [skip_paren('$1'),
+ skip_paren('$3')]}.
+type_200 -> type_300 : '$1'.
+
+type_300 -> type_300 add_op type_400 : ?mkop2(skip_paren('$1'),
+ '$2', skip_paren('$3')).
+type_300 -> type_400 : '$1'.
+
+type_400 -> type_400 mult_op type_500 : ?mkop2(skip_paren('$1'),
+ '$2', skip_paren('$3')).
+type_400 -> type_500 : '$1'.
+
+type_500 -> prefix_op type : ?mkop1('$1', skip_paren('$2')).
+type_500 -> type : '$1'.
type -> '(' top_type ')' : {paren_type, ?line('$2'), ['$2']}.
type -> var : '$1'.
@@ -134,7 +151,7 @@ type -> atom ':' atom '(' top_types ')' : {remote_type, ?line('$1'),
['$1', '$3', '$5']}.
type -> '[' ']' : {type, ?line('$1'), nil, []}.
type -> '[' top_type ']' : {type, ?line('$1'), list, ['$2']}.
-type -> '[' top_type ',' '.' '.' '.' ']' : {type, ?line('$1'),
+type -> '[' top_type ',' '...' ']' : {type, ?line('$1'),
nonempty_list, ['$2']}.
type -> '{' '}' : {type, ?line('$1'), tuple, []}.
type -> '{' top_types '}' : {type, ?line('$1'), tuple, '$2'}.
@@ -142,19 +159,13 @@ type -> '#' atom '{' '}' : {type, ?line('$1'), record, ['$2']}.
type -> '#' atom '{' field_types '}' : {type, ?line('$1'),
record, ['$2'|'$4']}.
type -> binary_type : '$1'.
-type -> int_type : '$1'.
-type -> int_type '.' '.' int_type : {type, ?line('$1'), range,
- ['$1', '$4']}.
+type -> integer : '$1'.
type -> 'fun' '(' ')' : {type, ?line('$1'), 'fun', []}.
type -> 'fun' '(' fun_type_100 ')' : '$3'.
-int_type -> integer : '$1'.
-int_type -> '-' integer : abstract(-normalise('$2'),
- ?line('$2')).
-
-fun_type_100 -> '(' '.' '.' '.' ')' '->' top_type
+fun_type_100 -> '(' '...' ')' '->' top_type
: {type, ?line('$1'), 'fun',
- [{type, ?line('$1'), any}, '$7']}.
+ [{type, ?line('$1'), any}, '$5']}.
fun_type_100 -> fun_type : '$1'.
fun_type -> '(' ')' '->' top_type : {type, ?line('$1'), 'fun',
@@ -179,9 +190,9 @@ binary_type -> '<<' bin_unit_type '>>' : {type, ?line('$1'),binary,
binary_type -> '<<' bin_base_type ',' bin_unit_type '>>'
: {type, ?line('$1'), binary, ['$2', '$4']}.
-bin_base_type -> var ':' integer : build_bin_type(['$1'], '$3').
+bin_base_type -> var ':' type : build_bin_type(['$1'], '$3').
-bin_unit_type -> var ':' var '*' integer : build_bin_type(['$1', '$3'], '$5').
+bin_unit_type -> var ':' var '*' type : build_bin_type(['$1', '$3'], '$5').
attr_val -> expr : ['$1'].
attr_val -> expr ',' exprs : ['$1' | '$3'].
@@ -597,11 +608,20 @@ find_arity_from_specs([Spec|_]) ->
{type, _, 'fun', [{type, _, product, Args},_]} = Fun,
length(Args).
+build_def(LHS, Types) ->
+ IsSubType = {atom, ?line(LHS), is_subtype},
+ {type, ?line(LHS), constraint, [IsSubType, [LHS, Types]]}.
+
lift_unions(T1, {type, _La, union, List}) ->
{type, ?line(T1), union, [T1|List]};
lift_unions(T1, T2) ->
{type, ?line(T1), union, [T1, T2]}.
+skip_paren({paren_type,_L,[Type]}) ->
+ skip_paren(Type);
+skip_paren(Type) ->
+ Type.
+
build_gen_type({atom, La, tuple}) ->
{type, La, tuple, any};
build_gen_type({atom, La, Name}) ->
@@ -610,7 +630,7 @@ build_gen_type({atom, La, Name}) ->
build_bin_type([{var, _, '_'}|Left], Int) ->
build_bin_type(Left, Int);
build_bin_type([], Int) ->
- Int;
+ skip_paren(Int);
build_bin_type([{var, La, _}|_], _) ->
ret_err(La, "Bad binary type").
diff --git a/lib/stdlib/src/erl_pp.erl b/lib/stdlib/src/erl_pp.erl
index 0859bf0466..df4a20b833 100644
--- a/lib/stdlib/src/erl_pp.erl
+++ b/lib/stdlib/src/erl_pp.erl
@@ -115,7 +115,7 @@ lattribute({attribute,_Line,Name,Arg}, Hook) ->
lattribute(module, {M,Vs}, _Hook) ->
attr("module",[{var,0,pname(M)},
- foldr(fun(V, C) -> {cons,0,{var,0,V},C}
+ foldr(fun(V, C) -> {cons,0,{var,0,V},C}
end, {nil,0}, Vs)]);
lattribute(module, M, _Hook) ->
attr("module", [{var,0,pname(M)}]);
@@ -140,7 +140,7 @@ typeattr(Tag, {TypeName,Type,Args}, _Hook) ->
ltype({ann_type,_Line,[V,T]}) ->
typed(lexpr(V, none), T);
ltype({paren_type,_Line,[T]}) ->
- [$(,ltype(T),$)];
+ [$(,ltype(T),$)];
ltype({type,_Line,union,Ts}) ->
{seq,[],[],[' |'],ltypes(Ts)};
ltype({type,_Line,list,[T]}) ->
@@ -153,7 +153,7 @@ ltype({type,Line,tuple,any}) ->
simple_type({atom,Line,tuple}, []);
ltype({type,_Line,tuple,Ts}) ->
tuple_type(Ts, fun ltype/1);
-ltype({type,_Line,record,[N|Fs]}) ->
+ltype({type,_Line,record,[{atom,_,N}|Fs]}) ->
record_type(N, Fs);
ltype({type,_Line,range,[_I1,_I2]=Es}) ->
expr_list(Es, '..', fun lexpr/2, none);
@@ -174,12 +174,15 @@ ltype({atom,_,T}) ->
ltype(E) ->
lexpr(E, 0, none).
-binary_type({integer,_,Int1}=I1, {integer,_,Int2}=I2) ->
- E1 = [[leaf("_:"),lexpr(I1, 0, none)] || Int1 =/= 0],
- E2 = [[leaf("_:_*"),lexpr(I2, 0, none)] || Int2 =/= 0],
+binary_type(I1, I2) ->
+ B = [[] || {integer,_,0} <- [I1]] =:= [],
+ U = [[] || {integer,_,0} <- [I2]] =:= [],
+ P = max_prec(),
+ E1 = [[leaf("_:"),lexpr(I1, P, none)] || B],
+ E2 = [[leaf("_:_*"),lexpr(I2, P, none)] || U],
{seq,'<<','>>',[$,],E1++E2}.
-record_type({atom,_,Name}, Fields) ->
+record_type(Name, Fields) ->
{first,[record_name(Name)],field_types(Fields)}.
field_types(Fs) ->
@@ -443,7 +446,7 @@ lexpr({op,_,Op,Arg}, Prec, Hook) ->
Ol = leaf(format("~s ", [Op])),
El = [Ol,lexpr(Arg, R, Hook)],
maybe_paren(P, Prec, El);
-lexpr({op,_,Op,Larg,Rarg}, Prec, Hook) when Op =:= 'orelse';
+lexpr({op,_,Op,Larg,Rarg}, Prec, Hook) when Op =:= 'orelse';
Op =:= 'andalso' ->
%% Breaks lines since R12B.
{L,P,R} = inop_prec(Op),
@@ -727,15 +730,15 @@ frmt(Item, I) ->
%%% and indentation are inserted between IPs.
%%% - {first,I,IP2}: IP2 follows after I, and is output with an indentation
%%% updated with the width of I.
-%%% - {seq,Before,After,Separator,IPs}: a sequence of Is separated by
-%%% Separator. Before is output before IPs, and the indentation of IPs
+%%% - {seq,Before,After,Separator,IPs}: a sequence of Is separated by
+%%% Separator. Before is output before IPs, and the indentation of IPs
%%% is updated with the width of Before. After follows after IPs.
%%% - {force_nl,ExtraInfo,I}: fun-info (a comment) forces linebreak before I.
%%% - {prefer_nl,Sep,IPs}: forces linebreak between Is unlesss negative
%%% indentation.
%%% - {string,S}: a string.
%%% - {hook,...}, {ehook,...}: hook expressions.
-%%%
+%%%
%%% list, first, seq, force_nl, and prefer_nl all accept IPs, where each
%%% element is either an item or a tuple {step|cstep,I1,I2}. step means
%%% that I2 is output after linebreak and an incremented indentation.
@@ -761,7 +764,7 @@ f({seq,Before,After,Sep,LItems}, I0, ST, WT) ->
{CharsL,SizeL} = unz(CharsSizeL),
{BCharsL,BSizeL} = unz1([BCharsSize]),
Sizes = BSizeL ++ SizeL,
- NSepChars = if
+ NSepChars = if
is_list(Sep), Sep =/= [] ->
erlang:max(0, length(CharsL)-1);
true ->
@@ -876,7 +879,7 @@ nl_indent(I, T) when I > 0 ->
[$\n|spaces(I, T)].
same_line(I0, SizeL, NSepChars) ->
- try
+ try
Size = lists:sum(SizeL) + NSepChars,
true = incr(I0, Size) =< ?MAXLINE,
{yes,Size}
@@ -956,9 +959,9 @@ write_a_string(S, N, Len) ->
-define(N_SPACES, 30).
spacetab() ->
- {[_|L],_} = mapfoldl(fun(_, A) -> {A,[$\s|A]}
+ {[_|L],_} = mapfoldl(fun(_, A) -> {A,[$\s|A]}
end, [], lists:seq(0, ?N_SPACES)),
- list_to_tuple(L).
+ list_to_tuple(L).
spaces(N, T) when N =< ?N_SPACES ->
element(N, T);
@@ -966,7 +969,7 @@ spaces(N, T) ->
[element(?N_SPACES, T)|spaces(N-?N_SPACES, T)].
wordtable() ->
- L = [begin {leaf,Sz,S} = leaf(W), {S,Sz} end ||
+ L = [begin {leaf,Sz,S} = leaf(W), {S,Sz} end ||
W <- [" ->"," =","<<",">>","[]","after","begin","case","catch",
"end","fun","if","of","receive","try","when"," ::","..",
" |"]],
diff --git a/lib/stdlib/src/erl_scan.erl b/lib/stdlib/src/erl_scan.erl
index 1013d54bdc..18f64c46d0 100644
--- a/lib/stdlib/src/erl_scan.erl
+++ b/lib/stdlib/src/erl_scan.erl
@@ -55,18 +55,13 @@
token_info/1,token_info/2,
attributes_info/1,attributes_info/2,set_attribute/3]).
-%%% Local record.
--record(erl_scan,
- {resword_fun=fun reserved_word/1,
- ws=false,
- comment=false,
- text=false}).
+-export_type([error_info/0, line/0, tokens_result/0]).
%%%
-%%% Exported functions
+%%% Defines and type definitions
%%%
--define(COLUMN(C), is_integer(C), C >= 1).
+-define(COLUMN(C), (is_integer(C) andalso C >= 1)).
%% Line numbers less than zero have always been allowed:
-define(ALINE(L), is_integer(L)).
-define(STRING(S), is_list(S)).
@@ -95,6 +90,15 @@
-type error_description() :: term().
-type error_info() :: {location(), module(), error_description()}.
+%%% Local record.
+-record(erl_scan,
+ {resword_fun = fun reserved_word/1 :: resword_fun(),
+ ws = false :: boolean(),
+ comment = false :: boolean(),
+ text = false :: boolean()}).
+
+%%----------------------------------------------------------------------------
+
-spec format_error(Error :: term()) -> string().
format_error({string,Quote,Head}) ->
lists:flatten(["unterminated " ++ string_thing(Quote) ++
@@ -307,10 +311,10 @@ options(Opt) ->
options([Opt]).
opts(Options, [Key|Keys], L) ->
- V = case lists:keysearch(Key, 1, Options) of
- {value,{reserved_word_fun,F}} when ?RESWORDFUN(F) ->
+ V = case lists:keyfind(Key, 1, Options) of
+ {reserved_word_fun,F} when ?RESWORDFUN(F) ->
{ok,F};
- {value,{Key,_}} ->
+ {Key,_} ->
badarg;
false ->
{ok,default_option(Key)}
@@ -333,12 +337,13 @@ expand_opt(O, Os) ->
[O|Os].
attr_info(Attrs, Item) ->
- case catch lists:keysearch(Item, 1, Attrs) of
- {value,{Item,Value}} ->
- {Item,Value};
+ try lists:keyfind(Item, 1, Attrs) of
+ {_Item, _Value} = T ->
+ T;
false ->
- undefined;
- _ ->
+ undefined
+ catch
+ _:_ ->
erlang:error(badarg, [Attrs, Item])
end.
@@ -442,6 +447,14 @@ scan1([$\%=C|Cs], St, Line, Col, Toks) ->
scan_comment(Cs, St, Line, Col, Toks, [C]);
scan1([C|Cs], St, Line, Col, Toks) when ?DIGIT(C) ->
scan_number(Cs, St, Line, Col, Toks, [C]);
+scan1("..."++Cs, St, Line, Col, Toks) ->
+ tok2(Cs, St, Line, Col, Toks, "...", '...', 3);
+scan1(".."=Cs, _St, Line, Col, Toks) ->
+ {more,{Cs,Col,Toks,Line,[],fun scan/6}};
+scan1(".."++Cs, St, Line, Col, Toks) ->
+ tok2(Cs, St, Line, Col, Toks, "..", '..', 2);
+scan1("."=Cs, _St, Line, Col, Toks) ->
+ {more,{Cs,Col,Toks,Line,[],fun scan/6}};
scan1([$.=C|Cs], St, Line, Col, Toks) ->
scan_dot(Cs, St, Line, Col, Toks, [C]);
scan1([$"|Cs], St, Line, Col, Toks) -> %" Emacs
@@ -644,8 +657,6 @@ scan_dot([$\n=C|Cs], St, Line, Col, Toks, Ncs) ->
scan_dot([C|Cs], St, Line, Col, Toks, Ncs) when ?WHITE_SPACE(C) ->
Attrs = attributes(Line, Col, St, Ncs++[C]),
{ok,[{dot,Attrs}|Toks],Cs,Line,incr_column(Col, 2)};
-scan_dot([]=Cs, _St, Line, Col, Toks, Ncs) ->
- {more,{Cs,Col,Toks,Line,Ncs,fun scan_dot/6}};
scan_dot(eof=Cs, St, Line, Col, Toks, Ncs) ->
Attrs = attributes(Line, Col, St, Ncs),
{ok,[{dot,Attrs}|Toks],Cs,Line,incr_column(Col, 1)};
diff --git a/lib/stdlib/src/ets.erl b/lib/stdlib/src/ets.erl
index d7b5dbc636..b0a197d784 100644
--- a/lib/stdlib/src/ets.erl
+++ b/lib/stdlib/src/ets.erl
@@ -42,6 +42,8 @@
-export([i/0, i/1, i/2, i/3]).
+-export_type([tab/0]).
+
%%------------------------------------------------------------------------------
-type tab() :: atom() | tid().
diff --git a/lib/stdlib/src/file_sorter.erl b/lib/stdlib/src/file_sorter.erl
index e21a0c88f3..3875eca39d 100644
--- a/lib/stdlib/src/file_sorter.erl
+++ b/lib/stdlib/src/file_sorter.erl
@@ -191,7 +191,7 @@ options([{format, Format} | L], Opts) when Format =:= binary;
options([{format, binary_term} | L], Opts) ->
options(L, Opts#opts{format = binary_term_fun()});
options([{size, Size} | L], Opts) when is_integer(Size), Size >= 0 ->
- options(L, Opts#opts{size = max(Size, 1)});
+ options(L, Opts#opts{size = erlang:max(Size, 1)});
options([{no_files, NoFiles} | L], Opts) when is_integer(NoFiles),
NoFiles > 1 ->
options(L, Opts#opts{no_files = NoFiles});
@@ -997,10 +997,10 @@ close_read_fun(Fd, FileName, fsort) ->
file:delete(FileName).
read_objs(Fd, FileName, I, L, Bin0, Size0, LSz, W) ->
- Max = max(Size0, ?CHUNKSIZE),
+ Max = erlang:max(Size0, ?CHUNKSIZE),
BSz0 = byte_size(Bin0),
Min = Size0 - BSz0 + W#w.hdlen, % Min > 0
- NoBytes = max(Min, Max),
+ NoBytes = erlang:max(Min, Max),
case read(Fd, FileName, NoBytes, W) of
{ok, Bin} ->
BSz = byte_size(Bin),
@@ -1180,9 +1180,6 @@ make_key2([Kp], T) ->
make_key2([Kp | Kps], T) ->
[element(Kp, T) | make_key2(Kps, T)].
-max(A, B) when A < B -> B;
-max(A, _) -> A.
-
infun(W) ->
W1 = W#w{in = undefined},
try (W#w.in)(read) of
diff --git a/lib/stdlib/src/gen.erl b/lib/stdlib/src/gen.erl
index 5aab547644..43df6f621d 100644
--- a/lib/stdlib/src/gen.erl
+++ b/lib/stdlib/src/gen.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).
@@ -212,7 +212,22 @@ do_call(Process, Label, Request, Timeout) ->
catch erlang:send(Process, {Label, {self(), Mref}, Request},
[noconnect]),
- wait_resp_mon(Node, Mref, Timeout)
+ receive
+ {Mref, Reply} ->
+ erlang:demonitor(Mref, [flush]),
+ {ok, Reply};
+ {'DOWN', Mref, _, _, noconnection} ->
+ exit({nodedown, Node});
+ {'DOWN', Mref, _, _, Reason} ->
+ exit(Reason)
+ after Timeout ->
+ erlang:demonitor(Mref),
+ receive
+ {'DOWN', Mref, _, _, _} -> true
+ after 0 -> true
+ end,
+ exit(timeout)
+ end
catch
error:_ ->
%% Node (C/Java?) is not supporting the monitor.
@@ -233,24 +248,6 @@ do_call(Process, Label, Request, Timeout) ->
end
end.
-wait_resp_mon(Node, Mref, Timeout) ->
- receive
- {Mref, Reply} ->
- erlang:demonitor(Mref, [flush]),
- {ok, Reply};
- {'DOWN', Mref, _, _, noconnection} ->
- exit({nodedown, Node});
- {'DOWN', Mref, _, _, Reason} ->
- exit(Reason)
- after Timeout ->
- erlang:demonitor(Mref),
- receive
- {'DOWN', Mref, _, _, _} -> true
- after 0 -> true
- end,
- exit(timeout)
- end.
-
wait_resp(Node, Tag, Timeout) ->
receive
{Tag, Reply} ->
diff --git a/lib/stdlib/src/gen_event.erl b/lib/stdlib/src/gen_event.erl
index 27ff9441e6..b1e9e3a02f 100644
--- a/lib/stdlib/src/gen_event.erl
+++ b/lib/stdlib/src/gen_event.erl
@@ -677,12 +677,23 @@ report_error(Handler, Reason, State, LastIn, SName) ->
_ ->
Reason
end,
+ Mod = Handler#handler.module,
+ FmtState = case erlang:function_exported(Mod, format_status, 2) of
+ true ->
+ Args = [get(), State],
+ case catch Mod:format_status(terminate, Args) of
+ {'EXIT', _} -> State;
+ Else -> Else
+ end;
+ _ ->
+ State
+ end,
error_msg("** gen_event handler ~p crashed.~n"
"** Was installed in ~p~n"
"** Last event was: ~p~n"
"** When handler state == ~p~n"
"** Reason == ~p~n",
- [handler(Handler),SName,LastIn,State,Reason1]).
+ [handler(Handler),SName,LastIn,FmtState,Reason1]).
handler(Handler) when not Handler#handler.id ->
Handler#handler.module;
@@ -711,10 +722,20 @@ get_modules(MSL) ->
%%-----------------------------------------------------------------
%% Status information
%%-----------------------------------------------------------------
-format_status(_Opt, StatusData) ->
- [_PDict, SysState, Parent, _Debug, [ServerName, MSL, _Hib]] = StatusData,
+format_status(Opt, StatusData) ->
+ [PDict, SysState, Parent, _Debug, [ServerName, MSL, _Hib]] = StatusData,
Header = lists:concat(["Status for event handler ", ServerName]),
+ FmtMSL = [case erlang:function_exported(Mod, format_status, 2) of
+ true ->
+ Args = [PDict, State],
+ case catch Mod:format_status(Opt, Args) of
+ {'EXIT', _} -> MSL;
+ Else -> MS#handler{state = Else}
+ end;
+ _ ->
+ MS
+ end || #handler{module = Mod, state = State} = MS <- MSL],
[{header, Header},
{data, [{"Status", SysState},
{"Parent", Parent}]},
- {items, {"Installed handlers", MSL}}].
+ {items, {"Installed handlers", FmtMSL}}].
diff --git a/lib/stdlib/src/gen_fsm.erl b/lib/stdlib/src/gen_fsm.erl
index 9961646418..7d9960b912 100644
--- a/lib/stdlib/src/gen_fsm.erl
+++ b/lib/stdlib/src/gen_fsm.erl
@@ -542,7 +542,18 @@ terminate(Reason, Name, Msg, Mod, StateName, StateData, Debug) ->
{shutdown,_}=Shutdown ->
exit(Shutdown);
_ ->
- error_info(Reason, Name, Msg, StateName, StateData, Debug),
+ FmtStateData =
+ case erlang:function_exported(Mod, format_status, 2) of
+ true ->
+ Args = [get(), StateData],
+ case catch Mod:format_status(terminate, Args) of
+ {'EXIT', _} -> StateData;
+ Else -> Else
+ end;
+ _ ->
+ StateData
+ end,
+ error_info(Reason,Name,Msg,StateName,FmtStateData,Debug),
exit(Reason)
end
end.
@@ -603,22 +614,27 @@ get_msg(Msg) -> Msg.
format_status(Opt, StatusData) ->
[PDict, SysState, Parent, Debug, [Name, StateName, StateData, Mod, _Time]] =
StatusData,
- NameTag = if is_pid(Name) ->
- pid_to_list(Name);
- is_atom(Name) ->
- Name
- end,
- Header = lists:concat(["Status for state machine ", NameTag]),
+ StatusHdr = "Status for state machine",
+ Header = if
+ is_pid(Name) ->
+ lists:concat([StatusHdr, " ", pid_to_list(Name)]);
+ is_atom(Name); is_list(Name) ->
+ lists:concat([StatusHdr, " ", Name]);
+ true ->
+ {StatusHdr, Name}
+ end,
Log = sys:get_debug(log, Debug, []),
- Specfic =
+ DefaultStatus = [{data, [{"StateData", StateData}]}],
+ Specfic =
case erlang:function_exported(Mod, format_status, 2) of
true ->
case catch Mod:format_status(Opt,[PDict,StateData]) of
- {'EXIT', _} -> [{data, [{"StateData", StateData}]}];
- Else -> Else
+ {'EXIT', _} -> DefaultStatus;
+ StatusList when is_list(StatusList) -> StatusList;
+ Else -> [Else]
end;
_ ->
- [{data, [{"StateData", StateData}]}]
+ DefaultStatus
end,
[{header, Header},
{data, [{"Status", SysState},
diff --git a/lib/stdlib/src/gen_server.erl b/lib/stdlib/src/gen_server.erl
index 1c9e5270b6..ac81df9cab 100644
--- a/lib/stdlib/src/gen_server.erl
+++ b/lib/stdlib/src/gen_server.erl
@@ -705,7 +705,18 @@ terminate(Reason, Name, Msg, Mod, State, Debug) ->
{shutdown,_}=Shutdown ->
exit(Shutdown);
_ ->
- error_info(Reason, Name, Msg, State, Debug),
+ FmtState =
+ case erlang:function_exported(Mod, format_status, 2) of
+ true ->
+ Args = [get(), State],
+ case catch Mod:format_status(terminate, Args) of
+ {'EXIT', _} -> State;
+ Else -> Else
+ end;
+ _ ->
+ State
+ end,
+ error_info(Reason, Name, Msg, FmtState, Debug),
exit(Reason)
end
end.
@@ -829,22 +840,27 @@ name_to_pid(Name) ->
%%-----------------------------------------------------------------
format_status(Opt, StatusData) ->
[PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData,
- NameTag = if is_pid(Name) ->
- pid_to_list(Name);
- is_atom(Name) ->
- Name
- end,
- Header = lists:concat(["Status for generic server ", NameTag]),
+ StatusHdr = "Status for generic server",
+ Header = if
+ is_pid(Name) ->
+ lists:concat([StatusHdr, " ", pid_to_list(Name)]);
+ is_atom(Name); is_list(Name) ->
+ lists:concat([StatusHdr, " ", Name]);
+ true ->
+ {StatusHdr, Name}
+ end,
Log = sys:get_debug(log, Debug, []),
- Specfic =
+ DefaultStatus = [{data, [{"State", State}]}],
+ Specfic =
case erlang:function_exported(Mod, format_status, 2) of
true ->
case catch Mod:format_status(Opt, [PDict, State]) of
- {'EXIT', _} -> [{data, [{"State", State}]}];
- Else -> Else
+ {'EXIT', _} -> DefaultStatus;
+ StatusList when is_list(StatusList) -> StatusList;
+ Else -> [Else]
end;
_ ->
- [{data, [{"State", State}]}]
+ DefaultStatus
end,
[{header, Header},
{data, [{"Status", SysState},
diff --git a/lib/stdlib/src/io.erl b/lib/stdlib/src/io.erl
index 1f8076e864..1d0f9374bc 100644
--- a/lib/stdlib/src/io.erl
+++ b/lib/stdlib/src/io.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(io).
@@ -32,6 +32,7 @@
parse_erl_form/1,parse_erl_form/2,parse_erl_form/3]).
-export([request/1,request/2,requests/1,requests/2]).
+-export_type([device/0, format/0]).
%%-------------------------------------------------------------------------
diff --git a/lib/stdlib/src/io_lib.erl b/lib/stdlib/src/io_lib.erl
index 26f6ec8931..4ca9d079b7 100644
--- a/lib/stdlib/src/io_lib.erl
+++ b/lib/stdlib/src/io_lib.erl
@@ -75,6 +75,8 @@
collect_line/2, collect_line/3, collect_line/4,
get_until/3, get_until/4]).
+-export_type([chars/0]).
+
%%----------------------------------------------------------------------
%% XXX: overapproximates a deep list of (unicode) characters
diff --git a/lib/stdlib/src/io_lib_fread.erl b/lib/stdlib/src/io_lib_fread.erl
index 74316dc730..33553692bc 100644
--- a/lib/stdlib/src/io_lib_fread.erl
+++ b/lib/stdlib/src/io_lib_fread.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(io_lib_fread).
@@ -22,6 +22,8 @@
-export([fread/2,fread/3]).
+-export_type([continuation/0, fread_2_ret/0, fread_3_ret/0]).
+
-import(lists, [reverse/1,reverse/2]).
%%-----------------------------------------------------------------------
diff --git a/lib/stdlib/src/lists.erl b/lib/stdlib/src/lists.erl
index 857eda8161..08ee595f4d 100644
--- a/lib/stdlib/src/lists.erl
+++ b/lib/stdlib/src/lists.erl
@@ -18,6 +18,9 @@
%%
-module(lists).
+-compile({no_auto_import,[max/2]}).
+-compile({no_auto_import,[min/2]}).
+
-export([append/2, append/1, subtract/2, reverse/1,
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,
diff --git a/lib/stdlib/src/proc_lib.erl b/lib/stdlib/src/proc_lib.erl
index 9aa5e0a71e..4fb64a3353 100644
--- a/lib/stdlib/src/proc_lib.erl
+++ b/lib/stdlib/src/proc_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%
%%
-module(proc_lib).
@@ -34,6 +34,8 @@
%% Internal exports.
-export([wake_up/3]).
+-export_type([spawn_option/0]).
+
%%-----------------------------------------------------------------------------
-type priority_level() :: 'high' | 'low' | 'max' | 'normal'.
diff --git a/lib/stdlib/src/proplists.erl b/lib/stdlib/src/proplists.erl
index 35d14891f1..6a45e0f868 100644
--- a/lib/stdlib/src/proplists.erl
+++ b/lib/stdlib/src/proplists.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%
%%
%% =====================================================================
@@ -49,6 +49,8 @@
%% ---------------------------------------------------------------------
+-export_type([property/0]).
+
-type property() :: atom() | tuple().
-type aliases() :: [{any(), any()}].
diff --git a/lib/stdlib/src/stdlib.app.src b/lib/stdlib/src/stdlib.app.src
index 3e52c48e42..9d15f01683 100644
--- a/lib/stdlib/src/stdlib.app.src
+++ b/lib/stdlib/src/stdlib.app.src
@@ -1,20 +1,20 @@
%% This is an -*- erlang -*- file.
%%
%% %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, stdlib,
@@ -23,6 +23,7 @@
{modules, [array,
base64,
beam_lib,
+ binary,
c,
calendar,
dets,
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index 22269a8d1b..f5d5441184 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -21,7 +21,7 @@
-behaviour(gen_server).
%% External exports
--export([start_link/2,start_link/3,
+-export([start_link/2, start_link/3,
start_child/2, restart_child/2,
delete_child/2, terminate_child/2,
which_children/1, count_children/1,
@@ -33,25 +33,47 @@
-export([init/1, handle_call/3, handle_info/2, terminate/2, code_change/3]).
-export([handle_cast/2]).
+-export_type([child_spec/0, strategy/0]).
+
+%%--------------------------------------------------------------------------
+
+-type child_id() :: pid() | 'undefined'.
+-type mfargs() :: {module(), atom(), [term()]}.
+-type modules() :: [module()] | 'dynamic'.
+-type restart() :: 'permanent' | 'transient' | 'temporary'.
+-type shutdown() :: 'brutal_kill' | timeout().
+-type worker() :: 'worker' | 'supervisor'.
+-type sup_name() :: {'local', atom()} | {'global', atom()}.
+-type sup_ref() :: atom() | {atom(), atom()} | {'global', atom()} | pid().
+-type child_spec() :: {term(),mfargs(),restart(),shutdown(),worker(),modules()}.
+
+-type strategy() :: 'one_for_all' | 'one_for_one'
+ | 'rest_for_one' | 'simple_one_for_one'.
+
+%%--------------------------------------------------------------------------
+
+-record(child, {% pid is undefined when child is not running
+ pid = undefined :: child_id(),
+ name,
+ mfargs :: mfargs(),
+ restart_type :: restart(),
+ shutdown :: shutdown(),
+ child_type :: worker(),
+ modules = [] :: modules()}).
+-type child() :: #child{}.
+
-define(DICT, dict).
-record(state, {name,
- strategy,
- children = [],
- dynamics = ?DICT:new(),
- intensity,
- period,
+ strategy :: strategy(),
+ children = [] :: [child()],
+ dynamics = ?DICT:new() :: ?DICT(),
+ intensity :: non_neg_integer(),
+ period :: pos_integer(),
restarts = [],
module,
args}).
-
--record(child, {pid = undefined, % pid is undefined when child is not running
- name,
- mfa,
- restart_type,
- shutdown,
- child_type,
- modules = []}).
+-type state() :: #state{}.
-define(is_simple(State), State#state.strategy =:= simple_one_for_one).
@@ -65,21 +87,40 @@ behaviour_info(_Other) ->
%%% Servers/processes should/could also be built using gen_server.erl.
%%% SupName = {local, atom()} | {global, atom()}.
%%% ---------------------------------------------------
+
+-type startlink_err() :: {'already_started', pid()} | 'shutdown' | term().
+-type startlink_ret() :: {'ok', pid()} | 'ignore' | {'error', startlink_err()}.
+
+-spec start_link(module(), term()) -> startlink_ret().
start_link(Mod, Args) ->
gen_server:start_link(supervisor, {self, Mod, Args}, []).
+-spec start_link(sup_name(), module(), term()) -> startlink_ret().
start_link(SupName, Mod, Args) ->
gen_server:start_link(SupName, supervisor, {SupName, Mod, Args}, []).
%%% ---------------------------------------------------
%%% Interface functions.
%%% ---------------------------------------------------
+
+-type info() :: term().
+-type startchild_err() :: 'already_present'
+ | {'already_started', child_id()} | term().
+-type startchild_ret() :: {'ok', child_id()} | {'ok', child_id(), info()}
+ | {'error', startchild_err()}.
+
+-spec start_child(sup_ref(), child_spec() | [term()]) -> startchild_ret().
start_child(Supervisor, ChildSpec) ->
call(Supervisor, {start_child, ChildSpec}).
+-type restart_err() :: 'running' | 'not_found' | 'simple_one_for_one' | term().
+-spec restart_child(sup_ref(), term()) ->
+ {'ok', child_id()} | {'ok', child_id(), info()} | {'error', restart_err()}.
restart_child(Supervisor, Name) ->
call(Supervisor, {restart_child, Name}).
+-type del_err() :: 'running' | 'not_found' | 'simple_one_for_one'.
+-spec delete_child(sup_ref(), term()) -> 'ok' | {'error', del_err()}.
delete_child(Supervisor, Name) ->
call(Supervisor, {delete_child, Name}).
@@ -89,9 +130,13 @@ delete_child(Supervisor, Name) ->
%% Note that the child is *always* terminated in some
%% way (maybe killed).
%%-----------------------------------------------------------------
+
+-type term_err() :: 'not_found' | 'simple_one_for_one'.
+-spec terminate_child(sup_ref(), term()) -> 'ok' | {'error', term_err()}.
terminate_child(Supervisor, Name) ->
call(Supervisor, {terminate_child, Name}).
+-spec which_children(sup_ref()) -> [{term(), child_id(), worker(), modules()}].
which_children(Supervisor) ->
call(Supervisor, which_children).
@@ -101,6 +146,7 @@ count_children(Supervisor) ->
call(Supervisor, Req) ->
gen_server:call(Supervisor, Req, infinity).
+-spec check_childspecs([child_spec()]) -> 'ok' | {'error', term()}.
check_childspecs(ChildSpecs) when is_list(ChildSpecs) ->
case check_startspec(ChildSpecs) of
{ok, _} -> ok;
@@ -113,6 +159,14 @@ check_childspecs(X) -> {error, {badarg, X}}.
%%% Initialize the supervisor.
%%%
%%% ---------------------------------------------------
+
+-type stop_rsn() :: 'shutdown' | {'bad_return', {module(),'init', term()}}
+ | {'bad_start_spec', term()} | {'start_spec', term()}
+ | {'supervisor_data', term()}.
+
+-spec init({sup_name(), module(), [term()]}) ->
+ {'ok', state()} | 'ignore' | {'stop', stop_rsn()}.
+
init({SupName, Mod, Args}) ->
process_flag(trap_exit, true),
case Mod:init(Args) of
@@ -158,12 +212,12 @@ init_dynamic(_State, StartSpec) ->
%%-----------------------------------------------------------------
%% Func: start_children/2
-%% Args: Children = [#child] in start order
-%% SupName = {local, atom()} | {global, atom()} | {pid(),Mod}
+%% Args: Children = [child()] in start order
+%% SupName = {local, atom()} | {global, atom()} | {pid(), Mod}
%% Purpose: Start all children. The new list contains #child's
%% with pids.
%% Returns: {ok, NChildren} | {error, NChildren}
-%% NChildren = [#child] in termination order (reversed
+%% NChildren = [child()] in termination order (reversed
%% start order)
%%-----------------------------------------------------------------
start_children(Children, SupName) -> start_children(Children, [], SupName).
@@ -182,8 +236,8 @@ start_children([], NChildren, _SupName) ->
{ok, NChildren}.
do_start_child(SupName, Child) ->
- #child{mfa = {M, F, A}} = Child,
- case catch apply(M, F, A) of
+ #child{mfargs = {M, F, Args}} = Child,
+ case catch apply(M, F, Args) of
{ok, Pid} when is_pid(Pid) ->
NChild = Child#child{pid = Pid},
report_progress(NChild, SupName),
@@ -192,7 +246,7 @@ do_start_child(SupName, Child) ->
NChild = Child#child{pid = Pid},
report_progress(NChild, SupName),
{ok, Pid, Extra};
- ignore ->
+ ignore ->
{ok, undefined};
{error, What} -> {error, What};
What -> {error, What}
@@ -211,15 +265,17 @@ do_start_child_i(M, F, A) ->
What ->
{error, What}
end.
-
%%% ---------------------------------------------------
%%%
%%% Callback functions.
%%%
%%% ---------------------------------------------------
+-type call() :: 'which_children' | 'count_children' | {_, _}. % XXX: refine
+-spec handle_call(call(), term(), state()) -> {'reply', term(), state()}.
+
handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
- #child{mfa = {M, F, A}} = hd(State#state.children),
+ #child{mfargs = {M, F, A}} = hd(State#state.children),
Args = A ++ EArgs,
case do_start_child_i(M, F, Args) of
{ok, Pid} ->
@@ -235,7 +291,7 @@ handle_call({start_child, EArgs}, _From, State) when ?is_simple(State) ->
end;
%%% The requests terminate_child, delete_child and restart_child are
-%%% invalid for simple_one_for_one supervisors.
+%%% invalid for simple_one_for_one supervisors.
handle_call({_Req, _Data}, _From, State) when ?is_simple(State) ->
{reply, {error, simple_one_for_one}, State};
@@ -297,7 +353,7 @@ handle_call(which_children, _From, State) ->
Resp =
lists:map(fun(#child{pid = Pid, name = Name,
child_type = ChildType, modules = Mods}) ->
- {Name, Pid, ChildType, Mods}
+ {Name, Pid, ChildType, Mods}
end,
State#state.children),
{reply, Resp, State};
@@ -318,7 +374,6 @@ handle_call(count_children, _From, State) when ?is_simple(State) ->
{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) ->
@@ -347,15 +402,19 @@ count_child(#child{pid = Pid, child_type = supervisor},
%%% Hopefully cause a function-clause as there is no API function
%%% that utilizes cast.
+-spec handle_cast('null', state()) -> {'noreply', state()}.
+
handle_cast(null, State) ->
error_logger:error_msg("ERROR: Supervisor received cast-message 'null'~n",
[]),
-
{noreply, State}.
%%
%% Take care of terminated children.
%%
+-spec handle_info(term(), state()) ->
+ {'noreply', state()} | {'stop', 'shutdown', state()}.
+
handle_info({'EXIT', Pid, Reason}, State) ->
case restart_child(Pid, Reason, State) of
{ok, State1} ->
@@ -368,9 +427,12 @@ handle_info(Msg, State) ->
error_logger:error_msg("Supervisor received unexpected message: ~p~n",
[Msg]),
{noreply, State}.
+
%%
%% Terminate this server.
%%
+-spec terminate(term(), state()) -> 'ok'.
+
terminate(_Reason, State) ->
terminate_children(State#state.children, State#state.name),
ok.
@@ -384,6 +446,9 @@ terminate(_Reason, State) ->
%% NOTE: This requires that the init function of the call-back module
%% does not have any side effects.
%%
+-spec code_change(term(), state(), term()) ->
+ {'ok', state()} | {'error', term()}.
+
code_change(_, State, _) ->
case (State#state.module):init(State#state.args) of
{ok, {SupFlags, StartSpec}} ->
@@ -411,7 +476,7 @@ check_flags({Strategy, MaxIntensity, Period}) ->
check_flags(What) ->
{bad_flags, What}.
-update_childspec(State, StartSpec) when ?is_simple(State) ->
+update_childspec(State, StartSpec) when ?is_simple(State) ->
case check_startspec(StartSpec) of
{ok, [Child]} ->
{ok, State#state{children = [Child]}};
@@ -437,7 +502,7 @@ update_childspec1([Child|OldC], Children, KeepOld) ->
update_childspec1(OldC, Children, [Child|KeepOld])
end;
update_childspec1([], Children, KeepOld) ->
- % Return them in (keeped) reverse start order.
+ %% Return them in (kept) reverse start order.
lists:reverse(Children ++ KeepOld).
update_chsp(OldCh, Children) ->
@@ -482,7 +547,7 @@ handle_start_child(Child, State) ->
%%% ---------------------------------------------------
%%% Restart. A process has terminated.
-%%% Returns: {ok, #state} | {shutdown, #state}
+%%% Returns: {ok, state()} | {shutdown, state()}
%%% ---------------------------------------------------
restart_child(Pid, Reason, State) when ?is_simple(State) ->
@@ -490,19 +555,19 @@ restart_child(Pid, Reason, State) when ?is_simple(State) ->
{ok, Args} ->
[Child] = State#state.children,
RestartType = Child#child.restart_type,
- {M, F, _} = Child#child.mfa,
- NChild = Child#child{pid = Pid, mfa = {M, F, Args}},
+ {M, F, _} = Child#child.mfargs,
+ NChild = Child#child{pid = Pid, mfargs = {M, F, Args}},
do_restart(RestartType, Reason, NChild, State);
error ->
{ok, State}
end;
restart_child(Pid, Reason, State) ->
Children = State#state.children,
- case lists:keysearch(Pid, #child.pid, Children) of
- {value, Child} ->
+ case lists:keyfind(Pid, #child.pid, Children) of
+ #child{} = Child ->
RestartType = Child#child.restart_type,
do_restart(RestartType, Reason, Child, State);
- _ ->
+ false ->
{ok, State}
end.
@@ -534,7 +599,7 @@ restart(Child, State) ->
end.
restart(simple_one_for_one, Child, State) ->
- #child{mfa = {M, F, A}} = Child,
+ #child{mfargs = {M, F, A}} = Child,
Dynamics = ?DICT:erase(Child#child.pid, State#state.dynamics),
case do_start_child_i(M, F, A) of
{ok, Pid} ->
@@ -580,9 +645,9 @@ restart(one_for_all, Child, State) ->
%%-----------------------------------------------------------------
%% Func: terminate_children/2
-%% Args: Children = [#child] in termination order
+%% Args: Children = [child()] in termination order
%% SupName = {local, atom()} | {global, atom()} | {pid(),Mod}
-%% Returns: NChildren = [#child] in
+%% Returns: NChildren = [child()] in
%% startup order (reversed termination order)
%%-----------------------------------------------------------------
terminate_children(Children, SupName) ->
@@ -617,7 +682,6 @@ do_terminate(Child, _SupName) ->
%% Returns: ok | {error, OtherReason} (this should be reported)
%%-----------------------------------------------------------------
shutdown(Pid, brutal_kill) ->
-
case monitor_child(Pid) of
ok ->
exit(Pid, kill),
@@ -630,9 +694,7 @@ shutdown(Pid, brutal_kill) ->
{error, Reason} ->
{error, Reason}
end;
-
shutdown(Pid, Time) ->
-
case monitor_child(Pid) of
ok ->
exit(Pid, shutdown), %% Try to shutdown gracefully
@@ -738,9 +800,9 @@ remove_child(Child, State) ->
%% MaxIntensity = integer()
%% Period = integer()
%% Mod :== atom()
-%% Arsg :== term()
+%% Args :== term()
%% Purpose: Check that Type is of correct type (!)
-%% Returns: {ok, #state} | Error
+%% Returns: {ok, state()} | Error
%%-----------------------------------------------------------------
init_state(SupName, Type, Mod, Args) ->
case catch init_state1(SupName, Type, Mod, Args) of
@@ -755,11 +817,11 @@ init_state1(SupName, {Strategy, MaxIntensity, Period}, Mod, Args) ->
validIntensity(MaxIntensity),
validPeriod(Period),
{ok, #state{name = supname(SupName,Mod),
- strategy = Strategy,
- intensity = MaxIntensity,
- period = Period,
- module = Mod,
- args = Args}};
+ strategy = Strategy,
+ intensity = MaxIntensity,
+ period = Period,
+ module = Mod,
+ args = Args}};
init_state1(_SupName, Type, _, _) ->
{invalid_type, Type}.
@@ -771,26 +833,26 @@ validStrategy(What) -> throw({invalid_strategy, What}).
validIntensity(Max) when is_integer(Max),
Max >= 0 -> true;
-validIntensity(What) -> throw({invalid_intensity, What}).
+validIntensity(What) -> throw({invalid_intensity, What}).
validPeriod(Period) when is_integer(Period),
Period > 0 -> true;
validPeriod(What) -> throw({invalid_period, What}).
-supname(self,Mod) -> {self(),Mod};
-supname(N,_) -> N.
+supname(self, Mod) -> {self(), Mod};
+supname(N, _) -> N.
%%% ------------------------------------------------------
%%% Check that the children start specification is valid.
%%% Shall be a six (6) tuple
%%% {Name, Func, RestartType, Shutdown, ChildType, Modules}
%%% where Name is an atom
-%%% Func is {Mod, Fun, Args} == {atom, atom, list}
+%%% Func is {Mod, Fun, Args} == {atom(), atom(), list()}
%%% RestartType is permanent | temporary | transient
%%% Shutdown = integer() | infinity | brutal_kill
%%% ChildType = supervisor | worker
%%% Modules = [atom()] | dynamic
-%%% Returns: {ok, [#child]} | Error
+%%% Returns: {ok, [child()]} | Error
%%% ------------------------------------------------------
check_startspec(Children) -> check_startspec(Children, []).
@@ -818,14 +880,14 @@ check_childspec(Name, Func, RestartType, Shutdown, ChildType, Mods) ->
validChildType(ChildType),
validShutdown(Shutdown, ChildType),
validMods(Mods),
- {ok, #child{name = Name, mfa = Func, restart_type = RestartType,
+ {ok, #child{name = Name, mfargs = Func, restart_type = RestartType,
shutdown = Shutdown, child_type = ChildType, modules = Mods}}.
validChildType(supervisor) -> true;
validChildType(worker) -> true;
validChildType(What) -> throw({invalid_child_type, What}).
-validName(_Name) -> true.
+validName(_Name) -> true.
validFunc({M, F, A}) when is_atom(M),
is_atom(F),
@@ -923,7 +985,7 @@ report_error(Error, Reason, Child, SupName) ->
extract_child(Child) ->
[{pid, Child#child.pid},
{name, Child#child.name},
- {mfa, Child#child.mfa},
+ {mfargs, Child#child.mfargs},
{restart_type, Child#child.restart_type},
{shutdown, Child#child.shutdown},
{child_type, Child#child.child_type}].
diff --git a/lib/stdlib/src/timer.erl b/lib/stdlib/src/timer.erl
index 36fdb48c75..6ee837c3e6 100644
--- a/lib/stdlib/src/timer.erl
+++ b/lib/stdlib/src/timer.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).
@@ -41,54 +41,54 @@
%%
%% Time is in milliseconds.
%%
--opaque tref() :: any().
+-opaque tref() :: {integer(), reference()}.
-type time() :: non_neg_integer().
-type timestamp() :: {non_neg_integer(), non_neg_integer(), non_neg_integer()}.
%%
%% Interface functions
%%
--spec apply_after(time(), atom(), atom(), [_]) -> {'ok', tref()} | {'error', _}.
+-spec apply_after(time(), atom(), atom(), [term()]) -> {'ok', tref()} | {'error', term()}.
apply_after(Time, M, F, A) ->
req(apply_after, {Time, {M, F, A}}).
--spec send_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', _}.
+-spec send_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}.
send_after(Time, Pid, Message) ->
req(apply_after, {Time, {?MODULE, send, [Pid, Message]}}).
--spec send_after(time(), _) -> {'ok', tref()} | {'error', _}.
+-spec send_after(time(), term()) -> {'ok', tref()} | {'error', term()}.
send_after(Time, Message) ->
send_after(Time, self(), Message).
--spec exit_after(time(), pid() | atom(), _) -> {'ok', tref()} | {'error', _}.
+-spec exit_after(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}.
exit_after(Time, Pid, Reason) ->
req(apply_after, {Time, {erlang, exit, [Pid, Reason]}}).
--spec exit_after(time(), term()) -> {'ok', tref()} | {'error', _}.
+-spec exit_after(time(), term()) -> {'ok', tref()} | {'error', term()}.
exit_after(Time, Reason) ->
exit_after(Time, self(), Reason).
--spec kill_after(time(), pid() | atom()) -> {'ok', tref()} | {'error', _}.
+-spec kill_after(time(), pid() | atom()) -> {'ok', tref()} | {'error', term()}.
kill_after(Time, Pid) ->
exit_after(Time, Pid, kill).
--spec kill_after(time()) -> {'ok', tref()} | {'error', _}.
+-spec kill_after(time()) -> {'ok', tref()} | {'error', term()}.
kill_after(Time) ->
exit_after(Time, self(), kill).
--spec apply_interval(time(), atom(), atom(), [_]) -> {'ok', tref()} | {'error', _}.
+-spec apply_interval(time(), atom(), atom(), [term()]) -> {'ok', tref()} | {'error', term()}.
apply_interval(Time, M, F, A) ->
req(apply_interval, {Time, self(), {M, F, A}}).
--spec send_interval(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', _}.
+-spec send_interval(time(), pid() | atom(), term()) -> {'ok', tref()} | {'error', term()}.
send_interval(Time, Pid, Message) ->
req(apply_interval, {Time, Pid, {?MODULE, send, [Pid, Message]}}).
--spec send_interval(time(), term()) -> {'ok', tref()} | {'error', _}.
+-spec send_interval(time(), term()) -> {'ok', tref()} | {'error', term()}.
send_interval(Time, Message) ->
send_interval(Time, self(), Message).
--spec cancel(tref()) -> {'ok', 'cancel'} | {'error', _}.
+-spec cancel(tref()) -> {'ok', 'cancel'} | {'error', term()}.
cancel(BRef) ->
req(cancel, BRef).
@@ -101,7 +101,7 @@ sleep(T) ->
%%
%% Measure the execution time (in microseconds) for an MFA.
%%
--spec tc(atom(), atom(), [_]) -> {time(), term()}.
+-spec tc(atom(), atom(), [term()]) -> {time(), term()}.
tc(M, F, A) ->
Before = erlang:now(),
Val = (catch apply(M, F, A)),
@@ -141,7 +141,7 @@ hms(H, M, S) ->
start() ->
ensure_started().
--spec start_link() -> {'ok', pid()} | {'error', _}.
+-spec start_link() -> {'ok', pid()} | {'error', term()}.
start_link() ->
gen_server:start_link({local, timer_server}, ?MODULE, [], []).
@@ -152,6 +152,7 @@ init([]) ->
?INTERVAL_TAB = ets:new(?INTERVAL_TAB, [named_table,protected]),
{ok, [], infinity}.
+-spec ensure_started() -> 'ok'.
ensure_started() ->
case whereis(timer_server) of
undefined ->
@@ -175,6 +176,10 @@ req(Req, Arg) ->
%%
%% Time and Timeout is in milliseconds. Started is in microseconds.
%%
+-type timers() :: term(). % XXX: refine?
+
+-spec handle_call(term(), term(), timers()) ->
+ {'reply', term(), timers(), timeout()} | {'noreply', timers(), timeout()}.
handle_call({apply_after, {Time, Op}, Started}, _From, _Ts)
when is_integer(Time), Time >= 0 ->
BRef = {Started + 1000*Time, make_ref()},
@@ -194,7 +199,7 @@ handle_call({apply_interval, {Time, To, MFA}, Started}, _From, _Ts)
Interval = Time*1000,
BRef2 = {Started + Interval, Ref},
Timer = {BRef2, {repeat, Interval, Pid}, MFA},
- ets:insert(?INTERVAL_TAB,{BRef1,BRef2,Pid}),
+ ets:insert(?INTERVAL_TAB, {BRef1,BRef2,Pid}),
ets:insert(?TIMER_TAB, Timer),
Timeout = timer_timeout(SysTime),
{reply, {ok, BRef1}, [], Timeout};
@@ -202,7 +207,7 @@ handle_call({apply_interval, {Time, To, MFA}, Started}, _From, _Ts)
{reply, {error, badarg}, [], next_timeout()}
end;
handle_call({cancel, BRef = {_Time, Ref}, _}, _From, Ts)
- when is_reference(Ref) ->
+ when is_reference(Ref) ->
delete_ref(BRef),
{reply, {ok, cancel}, Ts, next_timeout()};
handle_call({cancel, _BRef, _}, _From, Ts) ->
@@ -214,6 +219,7 @@ handle_call({apply_interval, _, _}, _From, Ts) ->
handle_call(_Else, _From, Ts) -> % Catch anything else
{noreply, Ts, next_timeout()}.
+-spec handle_info(term(), timers()) -> {'noreply', timers(), timeout()}.
handle_info(timeout, Ts) -> % Handle timeouts
Timeout = timer_timeout(system_time()),
{noreply, Ts, Timeout};
@@ -223,19 +229,21 @@ handle_info({'EXIT', Pid, _Reason}, Ts) -> % Oops, someone died
handle_info(_OtherMsg, Ts) -> % Other Msg's
{noreply, Ts, next_timeout()}.
+-spec handle_cast(term(), timers()) -> {'noreply', timers(), timeout()}.
handle_cast(_Req, Ts) -> % Not predicted but handled
{noreply, Ts, next_timeout()}.
--spec terminate(_, _) -> 'ok'.
+-spec terminate(term(), _State) -> 'ok'.
terminate(_Reason, _State) ->
ok.
+-spec code_change(term(), State, term()) -> {'ok', State}.
code_change(_OldVsn, State, _Extra) ->
%% According to the man for gen server no timer can be set here.
{ok, State}.
%%
-%% timer_timeout(Timers, SysTime)
+%% timer_timeout(SysTime)
%%
%% Apply and remove already timed-out timers. A timer is a tuple
%% {Time, BRef, Op, MFA}, where Time is in microseconds.
@@ -279,12 +287,13 @@ delete_ref(BRef = {interval, _}) ->
ok
end;
delete_ref(BRef) ->
- ets:delete(?TIMER_TAB,BRef).
+ ets:delete(?TIMER_TAB, BRef).
%%
%% pid_delete
%%
+-spec pid_delete(pid()) -> 'ok'.
pid_delete(Pid) ->
IntervalTimerList =
ets:select(?INTERVAL_TAB,
@@ -292,13 +301,14 @@ pid_delete(Pid) ->
[{'==','$1',Pid}],
['$_']}]),
lists:foreach(fun({IntKey, TimerKey, _ }) ->
- ets:delete(?INTERVAL_TAB,IntKey),
- ets:delete(?TIMER_TAB,TimerKey)
+ ets:delete(?INTERVAL_TAB, IntKey),
+ ets:delete(?TIMER_TAB, TimerKey)
end, IntervalTimerList).
%% Calculate time to the next timeout. Returned timeout must fit in a
%% small int.
+-spec next_timeout() -> timeout().
next_timeout() ->
case ets:first(?TIMER_TAB) of
'$end_of_table' ->
@@ -358,7 +368,7 @@ get_pid(_) ->
get_status() ->
Info1 = ets:info(?TIMER_TAB),
- {value,{size,TotalNumTimers}} = lists:keysearch(size, 1, Info1),
+ {size,TotalNumTimers} = lists:keyfind(size, 1, Info1),
Info2 = ets:info(?INTERVAL_TAB),
- {value,{size,NumIntervalTimers}} = lists:keysearch(size, 1, Info2),
+ {size,NumIntervalTimers} = lists:keyfind(size, 1, Info2),
{{?TIMER_TAB,TotalNumTimers},{?INTERVAL_TAB,NumIntervalTimers}}.
diff --git a/lib/stdlib/test/Makefile b/lib/stdlib/test/Makefile
index 9beac93eb8..3bbd9ce318 100644
--- a/lib/stdlib/test/Makefile
+++ b/lib/stdlib/test/Makefile
@@ -9,6 +9,8 @@ MODULES= \
array_SUITE \
base64_SUITE \
beam_lib_SUITE \
+ binary_module_SUITE \
+ binref \
c_SUITE \
calendar_SUITE \
dets_SUITE \
diff --git a/lib/stdlib/test/binary_module_SUITE.erl b/lib/stdlib/test/binary_module_SUITE.erl
new file mode 100644
index 0000000000..16ed9a2c26
--- /dev/null
+++ b/lib/stdlib/test/binary_module_SUITE.erl
@@ -0,0 +1,1323 @@
+-module(binary_module_SUITE).
+
+-export([all/1, interesting/1,random_ref_comp/1,random_ref_sr_comp/1,
+ random_ref_fla_comp/1,parts/1, bin_to_list/1, list_to_bin/1,
+ copy/1, referenced/1,guard/1,encode_decode/1,badargs/1,longest_common_trap/1]).
+
+-export([random_number/1, make_unaligned/1]).
+
+
+
+%%-define(STANDALONE,1).
+
+-ifdef(STANDALONE).
+
+-define(line,erlang:display({?MODULE,?LINE}),).
+
+-else.
+
+-include("test_server.hrl").
+-export([init_per_testcase/2, fin_per_testcase/2]).
+% Default timetrap timeout (set in init_per_testcase).
+% Some of these testcases are really heavy...
+-define(default_timeout, ?t:minutes(20)).
+
+-endif.
+
+
+
+-ifdef(STANDALONE).
+-export([run/0]).
+
+run() ->
+ [ apply(?MODULE,X,[[]]) || X <- all(suite) ].
+
+-else.
+
+init_per_testcase(_Case, Config) ->
+ ?line Dog = ?t:timetrap(?default_timeout),
+ [{watchdog, Dog} | Config].
+
+fin_per_testcase(_Case, Config) ->
+ ?line Dog = ?config(watchdog, Config),
+ ?line test_server:timetrap_cancel(Dog),
+ ok.
+-endif.
+
+all(suite) -> [interesting,random_ref_fla_comp,random_ref_sr_comp,
+ random_ref_comp,parts,bin_to_list, list_to_bin, copy,
+ referenced,guard,encode_decode,badargs,longest_common_trap].
+
+-define(MASK_ERROR(EXPR),mask_error((catch (EXPR)))).
+
+
+badargs(doc) ->
+ ["Tests various badarg exceptions in the module"];
+badargs(Config) when is_list(Config) ->
+ ?line badarg = ?MASK_ERROR(binary:compile_pattern([<<1,2,3:3>>])),
+ ?line badarg = ?MASK_ERROR(binary:compile_pattern([<<1,2,3>>|<<1,2>>])),
+ ?line badarg = ?MASK_ERROR(binary:compile_pattern(<<1,2,3:3>>)),
+ ?line badarg = ?MASK_ERROR(binary:compile_pattern(<<>>)),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3:3>>,<<1>>)),
+ ?line badarg = ?MASK_ERROR(binary:matches(<<1,2,3:3>>,<<1>>)),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,
+ [{scope,{0,1},1}])),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,
+ [{scape,{0,1}}])),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,
+ [{scope,{0,1,1}}])),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,[{scope,0,1}])),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,[{scope,[0,1]}])),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,
+ [{scope,{0.1,1}}])),
+ ?line badarg = ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,
+ [{scope,{1,1.1}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:match(<<1,2,3>>,<<1>>,
+ [{scope,{16#FF,
+ 16#FFFFFFFFFFFFFFFF}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:match(<<1,2,3>>,<<1>>,
+ [{scope,{16#FFFFFFFFFFFFFFFF,
+ -16#7FFFFFFFFFFFFFFF-1}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:match(<<1,2,3>>,<<1>>,
+ [{scope,{16#FFFFFFFFFFFFFFFF,
+ 16#7FFFFFFFFFFFFFFF}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:part(<<1,2,3>>,{16#FF,
+ 16#FFFFFFFFFFFFFFFF})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:part(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF,
+ -16#7FFFFFFFFFFFFFFF-1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:part(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF,
+ 16#7FFFFFFFFFFFFFFF})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:part(make_unaligned(<<1,2,3>>),{1,1,1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(make_unaligned(<<1,2,3>>),{1,1,1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(make_unaligned(<<1,2,3>>),{16#FFFFFFFFFFFFFFFF,
+ -16#7FFFFFFFFFFFFFFF-1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(make_unaligned(<<1,2,3>>),{16#FF,
+ 16#FFFFFFFFFFFFFFFF})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(make_unaligned(<<1,2,3>>),{16#FFFFFFFFFFFFFFFF,
+ 16#7FFFFFFFFFFFFFFF})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(make_unaligned(<<1,2,3>>),{16#FFFFFFFFFFFFFFFFFF,
+ -16#7FFF})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary_part(make_unaligned(<<1,2,3>>),{16#FF,
+ -16#7FFF})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>,{16#FF,
+ 16#FFFFFFFFFFFFFFFF})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF,
+ -16#7FFFFFFFFFFFFFFF-1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>,{16#FFFFFFFFFFFFFFFF,
+ 16#7FFFFFFFFFFFFFFF})),
+ ?line [1,2,3] =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>,[])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>,{1,2,3})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>,{1.0,1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3>>,{1,1.0})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3:3>>,{1,1})),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list(<<1,2,3:3>>)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:bin_to_list([1,2,3])),
+
+ ?line nomatch =
+ ?MASK_ERROR(binary:match(<<1,2,3>>,<<1>>,[{scope,{0,0}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:match(<<1,2,3>>,{bm,<<>>},[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:match(<<1,2,3>>,[],[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:match(<<1,2,3>>,{ac,<<>>},[{scope,{0,1}}])),
+ ?line {bm,BMMagic} = binary:compile_pattern([<<1,2,3>>]),
+ ?line {ac,ACMagic} = binary:compile_pattern([<<1,2,3>>,<<4,5>>]),
+ ?line badarg =
+ ?MASK_ERROR(binary:match(<<1,2,3>>,{bm,ACMagic},[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:match(<<1,2,3>>,{ac,BMMagic},[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:match(<<1,2,3>>,
+ {bm,ets:match_spec_compile([{'_',[],['$_']}])},
+ [{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:match(<<1,2,3>>,
+ {ac,ets:match_spec_compile([{'_',[],['$_']}])},
+ [{scope,{0,1}}])),
+ ?line nomatch =
+ ?MASK_ERROR(binary:matches(<<1,2,3>>,<<1>>,[{scope,{0,0}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:matches(<<1,2,3>>,{bm,<<>>},[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:matches(<<1,2,3>>,[],[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:matches(<<1,2,3>>,{ac,<<>>},[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:matches(<<1,2,3>>,{bm,ACMagic},[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:matches(<<1,2,3>>,{ac,BMMagic},[{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:matches(<<1,2,3>>,
+ {bm,ets:match_spec_compile([{'_',[],['$_']}])},
+ [{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:matches(<<1,2,3>>,
+ {ac,ets:match_spec_compile([{'_',[],['$_']}])},
+ [{scope,{0,1}}])),
+ ?line badarg =
+ ?MASK_ERROR(binary:longest_common_prefix(
+ [<<0:10000,1,2,4,1:3>>,
+ <<0:10000,1,2,3>>])),
+ ?line badarg =
+ ?MASK_ERROR(binary:longest_common_suffix(
+ [<<0:10000,1,2,4,1:3>>,
+ <<0:10000,1,2,3>>])),
+ ?line badarg =
+ ?MASK_ERROR(binary:encode_unsigned(-1)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:encode_unsigned(-16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:first(<<1,2,4,1:3>>)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:first([1,2,4])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:last(<<1,2,4,1:3>>)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:last([1,2,4])),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:at(<<1,2,4,1:3>>,2)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:at(<<>>,2)),
+ ?line badarg =
+ ?MASK_ERROR(
+ binary:at([1,2,4],2)),
+ ok.
+
+longest_common_trap(doc) ->
+ ["Whitebox test to force special trap conditions in longest_common_{prefix,suffix}"];
+longest_common_trap(Config) when is_list(Config) ->
+ ?line erts_debug:set_internal_state(available_internal_state,true),
+ ?line io:format("oldlimit: ~p~n",
+ [erts_debug:set_internal_state(binary_loop_limit,10)]),
+ erlang:bump_reductions(10000000),
+ ?line _ = binary:longest_common_prefix(
+ [<<0:10000,1,2,4>>,
+ <<0:10000,1,2,3>>,
+ <<0:10000,1,3,3>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,3>>,
+ <<0:10000,1,3,3>>,
+ <<0:10000,1,2,3>>,
+ <<0:10000,1,3,3>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,3>>,
+ <<0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0:10000,1,3,3>>,
+ <<0:10000,1,2,4>>]),
+ ?line _ = binary:longest_common_prefix(
+ [<<0:10000,1,2,4>>,
+ <<0:10000,1,2,3>>,
+ <<0:10000,1,3,3>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,3>>,
+ <<0:10000,1,3,3>>,
+ <<0:10000,1,2,3>>,
+ <<0:10000,1,3,3>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,4>>,
+ <<0:10000,1,2,3>>,
+ <<0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
+ <<0:10000,1,2,4>>]),
+ erlang:bump_reductions(10000000),
+ ?line _ = binary:longest_common_suffix(
+ [<<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,3,3,0:10000,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
+ <<1,2,4,0:10000>>]),
+ ?line _ = binary:longest_common_suffix(
+ [<<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<1,2,4,0:10000>>,
+ <<0,0,0,0,0,0,0,0,0,0,0,0,0,0>>,
+ <<1,2,4,0:10000>>]),
+ Subj = subj(),
+ Len = byte_size(Subj),
+ ?line Len = binary:longest_common_suffix(
+ [Subj,Subj,Subj]),
+ ?line io:format("limit was: ~p~n",
+ [erts_debug:set_internal_state(binary_loop_limit,
+ default)]),
+ ?line erts_debug:set_internal_state(available_internal_state,false),
+ ok.
+
+subj() ->
+ Me = self(),
+ spawn(fun() ->
+ X0 = iolist_to_binary([
+ "1234567890",
+ %lists:seq(16#21, 16#7e),
+ lists:duplicate(100, $x)
+ ]),
+ Me ! X0,
+ receive X -> X end
+ end),
+ X0 = receive A -> A end,
+ <<X1:32/binary,_/binary>> = X0,
+ Subject= <<X1/binary>>,
+ Subject.
+
+
+interesting(doc) ->
+ ["Try some interesting patterns"];
+interesting(Config) when is_list(Config) ->
+ X = do_interesting(binary),
+ X = do_interesting(binref).
+
+do_interesting(Module) ->
+ ?line {0,4} = Module:match(<<"123456">>,
+ Module:compile_pattern([<<"12">>,<<"1234">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>,<<"6">>])),
+ ?line [{0,4},{5,1}] = Module:matches(<<"123456">>,
+ Module:compile_pattern([<<"12">>,<<"1234">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>,<<"6">>])),
+ ?line [{0,4}] = Module:matches(<<"123456">>,
+ Module:compile_pattern([<<"12">>,<<"1234">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>])),
+ ?line [{0,2},{2,2}] = Module:matches(<<"123456">>,
+ Module:compile_pattern([<<"12">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>])),
+ ?line {1,4} = Module:match(<<"123456">>,
+ Module:compile_pattern([<<"34">>,<<"34">>,
+ <<"12347">>,<<"2345">>])),
+ ?line [{1,4}] = Module:matches(<<"123456">>,
+ Module:compile_pattern([<<"34">>,<<"34">>,
+ <<"12347">>,<<"2345">>])),
+ ?line [{2,2}] = Module:matches(<<"123456">>,
+ Module:compile_pattern([<<"34">>,<<"34">>,
+ <<"12347">>,<<"2346">>])),
+
+ ?line {0,4} = Module:match(<<"123456">>,
+ [<<"12">>,<<"1234">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>,<<"6">>]),
+ ?line [{0,4},{5,1}] = Module:matches(<<"123456">>,
+ [<<"12">>,<<"1234">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>,<<"6">>]),
+ ?line [{0,4}] = Module:matches(<<"123456">>,
+ [<<"12">>,<<"1234">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>]),
+ ?line [{0,2},{2,2}] = Module:matches(<<"123456">>,
+ [<<"12">>,
+ <<"23">>,<<"3">>,
+ <<"34">>,<<"456">>,
+ <<"45">>]),
+ ?line {1,4} = Module:match(<<"123456">>,
+ [<<"34">>,<<"34">>,
+ <<"12347">>,<<"2345">>]),
+ ?line [{1,4}] = Module:matches(<<"123456">>,
+ [<<"34">>,<<"34">>,
+ <<"12347">>,<<"2345">>]),
+ ?line [{2,2}] = Module:matches(<<"123456">>,
+ [<<"34">>,<<"34">>,
+ <<"12347">>,<<"2346">>]),
+ ?line nomatch = Module:match(<<1,2,3,4>>,<<2>>,[{scope,{0,1}}]),
+ ?line {1,1} = Module:match(<<1,2,3,4>>,<<2>>,[{scope,{0,2}}]),
+ ?line nomatch = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{0,2}}]),
+ ?line {1,2} = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{0,3}}]),
+ ?line {1,2} = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{0,4}}]),
+ ?line badarg = ?MASK_ERROR(Module:match(<<1,2,3,4>>,<<2,3>>,
+ [{scope,{0,5}}])),
+ ?line {1,2} = Module:match(<<1,2,3,4>>,<<2,3>>,[{scope,{4,-4}}]),
+ ?line {0,3} = Module:match(<<1,2,3,4>>,<<1,2,3>>,[{scope,{4,-4}}]),
+ ?line {0,4} = Module:match(<<1,2,3,4>>,<<1,2,3,4>>,[{scope,{4,-4}}]),
+ ?line badarg = ?MASK_ERROR(Module:match(<<1,2,3,4>>,<<1,2,3,4>>,
+ [{scope,{3,-4}}])),
+ ?line [] = Module:matches(<<1,2,3,4>>,<<2>>,[{scope,{0,1}}]),
+ ?line [{1,1}] = Module:matches(<<1,2,3,4>>,[<<2>>,<<3>>],[{scope,{0,2}}]),
+ ?line [] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{0,2}}]),
+ ?line [{1,2}] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{0,3}}]),
+ ?line [{1,2}] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{0,4}}]),
+ ?line [{1,2}] = Module:matches(<<1,2,3,4>>,[<<2,3>>,<<4>>],
+ [{scope,{0,3}}]),
+ ?line [{1,2},{3,1}] = Module:matches(<<1,2,3,4>>,[<<2,3>>,<<4>>],
+ [{scope,{0,4}}]),
+ ?line badarg = ?MASK_ERROR(Module:matches(<<1,2,3,4>>,<<2,3>>,
+ [{scope,{0,5}}])),
+ ?line [{1,2}] = Module:matches(<<1,2,3,4>>,<<2,3>>,[{scope,{4,-4}}]),
+ ?line [{1,2},{3,1}] = Module:matches(<<1,2,3,4>>,[<<2,3>>,<<4>>],
+ [{scope,{4,-4}}]),
+ ?line [{0,3}] = Module:matches(<<1,2,3,4>>,<<1,2,3>>,[{scope,{4,-4}}]),
+ ?line [{0,4}] = Module:matches(<<1,2,3,4>>,<<1,2,3,4>>,[{scope,{4,-4}}]),
+ ?line badarg = ?MASK_ERROR(Module:matches(<<1,2,3,4>>,<<1,2,3,4>>,
+ [{scope,{3,-4}}])),
+ ?line badarg = ?MASK_ERROR(Module:matches(<<1,2,3,4>>,[<<1,2,3,4>>],
+ [{scope,{3,-4}}])),
+ ?line [<<1,2,3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,<<4,5>>),
+ ?line [<<1,2,3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>]),
+ ?line [<<1,2,3>>,<<6>>,<<8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>],[global]),
+ ?line [<<1,2,3>>,<<6>>,<<>>,<<>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],
+ [global]),
+ ?line [<<1,2,3>>,<<6>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],
+ [global,trim]),
+ ?line [<<1,2,3,4,5,6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],
+ [global,trim,{scope,{0,4}}]),
+ ?line [<<1,2,3>>,<<6,7,8>>] = Module:split(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],
+ [global,trim,{scope,{0,5}}]),
+ ?line badarg = ?MASK_ERROR(
+ Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,
+ [global,trim,{scope,{0,5}}])),
+ ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,[]),
+ ?line <<1,2,3,99,6,99,99>> = Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,
+ [global]),
+ ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,
+ [global,{scope,{0,5}}]),
+ ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,
+ [global,{scope,{0,5}}]),
+ ?line <<1,2,3,99,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,
+ [global,{scope,{0,5}}]),
+ ?line badarg = ?MASK_ERROR(Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,
+ [global,{scope,{0,5}},
+ {insert,1}])),
+ ?line <<1,2,3,99,4,5,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<99>>,
+ [global,{scope,{0,5}},
+ {insert_replaced,1}]),
+ ?line <<1,2,3,9,4,5,9,6,7,8>> = Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],
+ <<9,9>>,
+ [global,{scope,{0,5}},
+ {insert_replaced,1}]),
+ ?line badarg = ?MASK_ERROR(Module:replace(<<1,2,3,4,5,6,7,8>>,
+ [<<4,5>>,<<7>>,<<8>>],<<>>,
+ [global,{scope,{0,5}},
+ {insert_replaced,1}])),
+ ?line 2 = Module:longest_common_prefix([<<1,2,4>>,<<1,2,3>>]),
+ ?line 2 = Module:longest_common_prefix([<<1,2,4>>,<<1,2>>]),
+ ?line 1 = Module:longest_common_prefix([<<1,2,4>>,<<1>>]),
+ ?line 0 = Module:longest_common_prefix([<<1,2,4>>,<<>>]),
+ ?line 1 = Module:longest_common_prefix([<<1,2,4>>,<<1,2,3>>,<<1,3,3>>]),
+ ?line 1 = Module:longest_common_prefix([<<1,2,4>>,<<1,2,3>>,<<1,3,3>>,<<1,2,4>>]),
+ ?line 1251 = Module:longest_common_prefix([<<0:10000,1,2,4>>,
+ <<0:10000,1,2,3>>,
+ <<0:10000,1,3,3>>,
+ <<0:10000,1,2,4>>]),
+ ?line 12501 = Module:longest_common_prefix([<<0:100000,1,2,4>>,
+ <<0:100000,1,2,3>>,
+ <<0:100000,1,3,3>>,
+ <<0:100000,1,2,4>>]),
+ ?line 1251 = Module:longest_common_prefix(
+ [make_unaligned(<<0:10000,1,2,4>>),
+ <<0:10000,1,2,3>>,
+ make_unaligned(<<0:10000,1,3,3>>),
+ <<0:10000,1,2,4>>]),
+ ?line 12501 = Module:longest_common_prefix(
+ [<<0:100000,1,2,4>>,
+ make_unaligned(<<0:100000,1,2,3>>),
+ <<0:100000,1,3,3>>,
+ make_unaligned(<<0:100000,1,2,4>>)]),
+ ?line 1250001 = Module:longest_common_prefix([<<0:10000000,1,2,4>>,
+ <<0:10000000,1,2,3>>,
+ <<0:10000000,1,3,3>>,
+ <<0:10000000,1,2,4>>]),
+ if % Too cruel for the reference implementation
+ Module =:= binary ->
+ ?line erts_debug:set_internal_state(available_internal_state,true),
+ ?line io:format("oldlimit: ~p~n",
+ [erts_debug:set_internal_state(
+ binary_loop_limit,100)]),
+ ?line 1250001 = Module:longest_common_prefix(
+ [<<0:10000000,1,2,4>>,
+ <<0:10000000,1,2,3>>,
+ <<0:10000000,1,3,3>>,
+ <<0:10000000,1,2,4>>]),
+ ?line io:format("limit was: ~p~n",
+ [erts_debug:set_internal_state(binary_loop_limit,
+ default)]),
+ ?line erts_debug:set_internal_state(available_internal_state,
+ false);
+ true ->
+ ok
+ end,
+ ?line 1 = Module:longest_common_suffix([<<0:100000000,1,2,4,5>>,
+ <<0:100000000,1,2,3,5>>,
+ <<0:100000000,1,3,3,5>>,
+ <<0:100000000,1,2,4,5>>]),
+ ?line 1 = Module:longest_common_suffix([<<1,2,4,5>>,
+ <<0:100000000,1,2,3,5>>,
+ <<0:100000000,1,3,3,5>>,
+ <<0:100000000,1,2,4,5>>]),
+ ?line 1 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5,5>>,
+ <<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4,5>>]),
+ ?line 0 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5,5>>,
+ <<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4>>]),
+ ?line 2 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5,5>>,
+ <<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4,5,5>>]),
+ ?line 1 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<5>>,
+ <<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4,5,5>>]),
+ ?line 0 = Module:longest_common_suffix([<<1,2,4,5,5>>,<<>>,
+ <<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4,5,5>>]),
+ ?line 0 = Module:longest_common_suffix([<<>>,<<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4,5,5>>]),
+ ?line 0 = Module:longest_common_suffix([<<>>,<<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4,5,5>>]),
+ ?line 2 = Module:longest_common_suffix([<<5,5>>,<<0:100000000,1,3,3,5,5>>,
+ <<0:100000000,1,2,4,5,5>>]),
+ ?line 2 = Module:longest_common_suffix([<<5,5>>,<<5,5>>,<<4,5,5>>]),
+ ?line 2 = Module:longest_common_suffix([<<5,5>>,<<5,5>>,<<5,5>>]),
+ ?line 3 = Module:longest_common_suffix([<<4,5,5>>,<<4,5,5>>,<<4,5,5>>]),
+ ?line 0 = Module:longest_common_suffix([<<>>]),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([])),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([apa])),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([[<<>>]])),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_suffix([[<<0>>,
+ <<1:9>>]])),
+ ?line 0 = Module:longest_common_prefix([<<>>]),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([])),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([apa])),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([[<<>>]])),
+ ?line badarg = ?MASK_ERROR(Module:longest_common_prefix([[<<0>>,
+ <<1:9>>]])),
+
+ ?line <<1:6,Bin:3/binary,_:2>> = <<1:6,1,2,3,1:2>>,
+ ?line <<1,2,3>> = Bin,
+ ?line 1 = Module:first(Bin),
+ ?line 1 = Module:first(<<1>>),
+ ?line 1 = Module:first(<<1,2,3>>),
+ ?line badarg = ?MASK_ERROR(Module:first(<<>>)),
+ ?line badarg = ?MASK_ERROR(Module:first(apa)),
+ ?line 3 = Module:last(Bin),
+ ?line 1 = Module:last(<<1>>),
+ ?line 3 = Module:last(<<1,2,3>>),
+ ?line badarg = ?MASK_ERROR(Module:last(<<>>)),
+ ?line badarg = ?MASK_ERROR(Module:last(apa)),
+ ?line 1 = Module:at(Bin,0),
+ ?line 1 = Module:at(<<1>>,0),
+ ?line 1 = Module:at(<<1,2,3>>,0),
+ ?line 2 = Module:at(<<1,2,3>>,1),
+ ?line 3 = Module:at(<<1,2,3>>,2),
+ ?line badarg = ?MASK_ERROR(Module:at(<<1,2,3>>,3)),
+ ?line badarg = ?MASK_ERROR(Module:at(<<1,2,3>>,-1)),
+ ?line badarg = ?MASK_ERROR(Module:at(<<1,2,3>>,apa)),
+ ?line "hejsan" = [ Module:at(<<"hejsan">>,I) || I <- lists:seq(0,5) ],
+
+ ?line badarg = ?MASK_ERROR(Module:bin_to_list(<<1,2,3>>,3,-4)),
+ ?line [1,2,3] = ?MASK_ERROR(Module:bin_to_list(<<1,2,3>>,3,-3)),
+
+ ?line badarg = ?MASK_ERROR(Module:decode_unsigned(<<1,2,1:2>>,big)),
+ ?line badarg = ?MASK_ERROR(Module:decode_unsigned(<<1,2,1:2>>,little)),
+ ?line badarg = ?MASK_ERROR(Module:decode_unsigned(apa)),
+ ?line badarg = ?MASK_ERROR(Module:decode_unsigned(125,little)),
+ ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<>>,little)),
+ ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<>>,big)),
+ ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<0>>,little)),
+ ?line 0 = ?MASK_ERROR(Module:decode_unsigned(<<0>>,big)),
+ ?line 0 = ?MASK_ERROR(Module:decode_unsigned(make_unaligned(<<0>>),
+ little)),
+ ?line 0 = ?MASK_ERROR(Module:decode_unsigned(make_unaligned(<<0>>),big)),
+ ?line badarg = ?MASK_ERROR(Module:encode_unsigned(apa)),
+ ?line badarg = ?MASK_ERROR(Module:encode_unsigned(125.3,little)),
+ ?line badarg = ?MASK_ERROR(Module:encode_unsigned({1},little)),
+ ?line badarg = ?MASK_ERROR(Module:encode_unsigned([1],little)),
+ ?line <<0>> = ?MASK_ERROR(Module:encode_unsigned(0,little)),
+ ?line <<0>> = ?MASK_ERROR(Module:encode_unsigned(0,big)),
+ ok.
+
+encode_decode(doc) ->
+ ["test binary:encode_unsigned/1,2 and binary:decode_unsigned/1,2"];
+encode_decode(Config) when is_list(Config) ->
+ ?line random:seed({1271,769940,559934}),
+ ?line ok = encode_decode_loop({1,200},1000), % Need to be long enough
+ % to create offheap binaries
+ ok.
+
+encode_decode_loop(_Range,0) ->
+ ok;
+encode_decode_loop(Range, X) ->
+ ?line N = random_number(Range),
+ ?line A = binary:encode_unsigned(N),
+ ?line B = binary:encode_unsigned(N,big),
+ ?line C = binref:encode_unsigned(N),
+ ?line D = binref:encode_unsigned(N,big),
+ ?line E = binary:encode_unsigned(N,little),
+ ?line F = binref:encode_unsigned(N,little),
+ ?line G = binary:decode_unsigned(A),
+ ?line H = binary:decode_unsigned(A,big),
+ ?line I = binref:decode_unsigned(A),
+ ?line J = binary:decode_unsigned(E,little),
+ ?line K = binref:decode_unsigned(E,little),
+ ?line L = binary:decode_unsigned(make_unaligned(A)),
+ ?line M = binary:decode_unsigned(make_unaligned(E),little),
+ ?line PaddedBig = <<0:48,A/binary>>,
+ ?line PaddedLittle = <<E/binary,0:48>>,
+ ?line O = binary:decode_unsigned(PaddedBig),
+ ?line P = binary:decode_unsigned(make_unaligned(PaddedBig)),
+ ?line Q = binary:decode_unsigned(PaddedLittle,little),
+ ?line R = binary:decode_unsigned(make_unaligned(PaddedLittle),little),
+ ?line S = binref:decode_unsigned(PaddedLittle,little),
+ ?line T = binref:decode_unsigned(PaddedBig),
+ case (((A =:= B) and (B =:= C) and (C =:= D)) and
+ ((E =:= F)) and
+ ((N =:= G) and (G =:= H) and (H =:= I) and
+ (I =:= J) and (J =:= K) and (K =:= L) and (L =:= M)) and
+ ((M =:= O) and (O =:= P) and (P =:= Q) and (Q =:= R) and
+ (R =:= S) and (S =:= T)))of
+ true ->
+ encode_decode_loop(Range,X-1);
+ _ ->
+ io:format("Failed to encode/decode ~w~n(Results ~p)~n",
+ [N,[A,B,C,D,E,F,G,H,I,J,K,L,M,x,O,P,Q,R,S,T]]),
+ exit(mismatch)
+ end.
+
+guard(doc) ->
+ ["Smoke test of the guard BIFs binary_part/2,3"];
+guard(Config) when is_list(Config) ->
+ {comment, "Guard tests are run in emulator test suite"}.
+
+referenced(doc) ->
+ ["Test refernced_byte_size/1 bif."];
+referenced(Config) when is_list(Config) ->
+ ?line badarg = ?MASK_ERROR(binary:referenced_byte_size([])),
+ ?line badarg = ?MASK_ERROR(binary:referenced_byte_size(apa)),
+ ?line badarg = ?MASK_ERROR(binary:referenced_byte_size({})),
+ ?line badarg = ?MASK_ERROR(binary:referenced_byte_size(1)),
+ ?line A = <<1,2,3>>,
+ ?line B = binary:copy(A,1000),
+ ?line 3 = binary:referenced_byte_size(A),
+ ?line 3000 = binary:referenced_byte_size(B),
+ ?line <<_:8,C:2/binary>> = A,
+ ?line 3 = binary:referenced_byte_size(C),
+ ?line 2 = binary:referenced_byte_size(binary:copy(C)),
+ ?line <<_:7,D:2/binary,_:1>> = A,
+ ?line 2 = binary:referenced_byte_size(binary:copy(D)),
+ ?line 3 = binary:referenced_byte_size(D),
+ ?line <<_:8,E:2/binary,_/binary>> = B,
+ ?line 3000 = binary:referenced_byte_size(E),
+ ?line 2 = binary:referenced_byte_size(binary:copy(E)),
+ ?line <<_:7,F:2/binary,_:1,_/binary>> = B,
+ ?line 2 = binary:referenced_byte_size(binary:copy(F)),
+ ?line 3000 = binary:referenced_byte_size(F),
+ ok.
+
+
+
+list_to_bin(doc) ->
+ ["Test list_to_bin/1 bif"];
+list_to_bin(Config) when is_list(Config) ->
+ %% Just some smoke_tests first, then go nuts with random cases
+ ?line badarg = ?MASK_ERROR(binary:list_to_bin({})),
+ ?line badarg = ?MASK_ERROR(binary:list_to_bin(apa)),
+ ?line badarg = ?MASK_ERROR(binary:list_to_bin(<<"apa">>)),
+ F1 = fun(L) ->
+ ?MASK_ERROR(binref:list_to_bin(L))
+ end,
+ F2 = fun(L) ->
+ ?MASK_ERROR(binary:list_to_bin(L))
+ end,
+ ?line random_iolist:run(1000,F1,F2),
+ ok.
+
+copy(doc) ->
+ ["Test copy/1,2 bif's"];
+copy(Config) when is_list(Config) ->
+ ?line <<1,2,3>> = binary:copy(<<1,2,3>>),
+ ?line RS = random_string({1,10000}),
+ ?line RS = RS2 = binary:copy(RS),
+ ?line false = erts_debug:same(RS,RS2),
+ ?line <<>> = ?MASK_ERROR(binary:copy(<<1,2,3>>,0)),
+ ?line badarg = ?MASK_ERROR(binary:copy(<<1,2,3:3>>,2)),
+ ?line badarg = ?MASK_ERROR(binary:copy([],0)),
+ ?line <<>> = ?MASK_ERROR(binary:copy(<<>>,0)),
+ ?line badarg = ?MASK_ERROR(binary:copy(<<1,2,3>>,1.0)),
+ ?line badarg = ?MASK_ERROR(binary:copy(<<1,2,3>>,
+ 16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)),
+ ?line <<>> = binary:copy(<<>>,10000),
+ ?line random:seed({1271,769940,559934}),
+ ?line ok = random_copy(3000),
+ ?line erts_debug:set_internal_state(available_internal_state,true),
+ ?line io:format("oldlimit: ~p~n",
+ [erts_debug:set_internal_state(binary_loop_limit,10)]),
+ ?line Subj = subj(),
+ ?line XX = binary:copy(Subj,1000),
+ ?line XX = binref:copy(Subj,1000),
+ ?line ok = random_copy(1000),
+ ?line kill_copy_loop(1000),
+ ?line io:format("limit was: ~p~n",
+ [erts_debug:set_internal_state(binary_loop_limit,
+ default)]),
+ ?line erts_debug:set_internal_state(available_internal_state,false),
+ ok.
+
+kill_copy_loop(0) ->
+ ok;
+kill_copy_loop(N) ->
+ {Pid,Ref} = spawn_monitor(fun() ->
+ ok = random_copy(1000)
+ end),
+ receive
+ after 10 ->
+ ok
+ end,
+ exit(Pid,kill),
+ receive
+ {'DOWN',Ref,process,Pid,_} ->
+ kill_copy_loop(N-1)
+ after 1000 ->
+ exit(did_not_die)
+ end.
+
+random_copy(0) ->
+ ok;
+random_copy(N) ->
+ Str = random_string({0,N}),
+ Num = random:uniform(N div 10+1),
+ A = ?MASK_ERROR(binary:copy(Str,Num)),
+ B = ?MASK_ERROR(binref:copy(Str,Num)),
+ C = ?MASK_ERROR(binary:copy(make_unaligned(Str),Num)),
+ case {(A =:= B), (B =:= C)} of
+ {true,true} ->
+ random_copy(N-1);
+ _ ->
+ io:format("Failed to pick copy ~s ~p times~n",
+ [Str,Num]),
+ io:format("A:~p,~nB:~p,~n,C:~p.~n",
+ [A,B,C]),
+ exit(mismatch)
+ end.
+
+bin_to_list(doc) ->
+ ["Test bin_to_list/1,2,3 bif's"];
+bin_to_list(Config) when is_list(Config) ->
+ %% Just some smoke_tests first, then go nuts with random cases
+ ?line X = <<1,2,3,4,0:1000000,5>>,
+ ?line Y = make_unaligned(X),
+ ?line LX = binary:bin_to_list(X),
+ ?line LX = binary:bin_to_list(X,0,byte_size(X)),
+ ?line LX = binary:bin_to_list(X,byte_size(X),-byte_size(X)),
+ ?line LX = binary:bin_to_list(X,{0,byte_size(X)}),
+ ?line LX = binary:bin_to_list(X,{byte_size(X),-byte_size(X)}),
+ ?line LY = binary:bin_to_list(Y),
+ ?line LY = binary:bin_to_list(Y,0,byte_size(Y)),
+ ?line LY = binary:bin_to_list(Y,byte_size(Y),-byte_size(Y)),
+ ?line LY = binary:bin_to_list(Y,{0,byte_size(Y)}),
+ ?line LY = binary:bin_to_list(Y,{byte_size(Y),-byte_size(Y)}),
+ ?line 1 = hd(LX),
+ ?line 5 = lists:last(LX),
+ ?line 1 = hd(LY),
+ ?line 5 = lists:last(LY),
+ ?line X = list_to_binary(LY),
+ ?line Y = list_to_binary(LY),
+ ?line X = list_to_binary(LY),
+ ?line [5] = lists:nthtail(byte_size(X)-1,LX),
+ ?line [0,5] = lists:nthtail(byte_size(X)-2,LX),
+ ?line [0,5] = lists:nthtail(byte_size(Y)-2,LY),
+ ?line random:seed({1271,769940,559934}),
+ ?line ok = random_bin_to_list(5000),
+ ok.
+
+random_bin_to_list(0) ->
+ ok;
+random_bin_to_list(N) ->
+ Str = random_string({1,N}),
+ Parts0 = random_parts(10,N),
+ Parts1 = Parts0 ++ [ {X+Y,-Y} || {X,Y} <- Parts0 ],
+ [ begin
+ try
+ true = ?MASK_ERROR(binary:bin_to_list(Str,Z)) =:=
+ ?MASK_ERROR(binref:bin_to_list(Str,Z)),
+ true = ?MASK_ERROR(binary:bin_to_list(Str,Z)) =:=
+ ?MASK_ERROR(binary:bin_to_list(make_unaligned(Str),Z))
+ catch
+ _:_ ->
+ io:format("Error, Str = <<\"~s\">>.~nZ = ~p.~n",
+ [Str,Z]),
+ exit(badresult)
+ end
+ end || Z <- Parts1 ],
+ [ begin
+ try
+ true = ?MASK_ERROR(binary:bin_to_list(Str,A,B)) =:=
+ ?MASK_ERROR(binref:bin_to_list(Str,A,B)),
+ true = ?MASK_ERROR(binary:bin_to_list(Str,A,B)) =:=
+ ?MASK_ERROR(binary:bin_to_list(make_unaligned(Str),A,B))
+ catch
+ _:_ ->
+ io:format("Error, Str = <<\"~s\">>.~nA = ~p.~nB = ~p.~n",
+ [Str,A,B]),
+ exit(badresult)
+ end
+ end || {A,B} <- Parts1 ],
+ random_bin_to_list(N-1).
+
+parts(doc) ->
+ ["Test the part/2,3 bif's"];
+parts(Config) when is_list(Config) ->
+ %% Some simple smoke tests to begin with
+ ?line Simple = <<1,2,3,4,5,6,7,8>>,
+ ?line <<1,2>> = binary:part(Simple,0,2),
+ ?line <<1,2>> = binary:part(Simple,{0,2}),
+ ?line Simple = binary:part(Simple,0,8),
+ ?line Simple = binary:part(Simple,{0,8}),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,0,9)),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{0,9})),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,1,8)),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{1,8})),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{3,-4})),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{3.0,1})),
+ ?line badarg = ?MASK_ERROR(
+ binary:part(Simple,{16#FFFFFFFFFFFFFFFFFFFFFFFFFFFFF
+ ,1})),
+ ?line <<2,3,4,5,6,7,8>> = binary:part(Simple,{1,7}),
+ ?line <<2,3,4,5,6,7,8>> = binary:part(Simple,{8,-7}),
+ ?line Simple = binary:part(Simple,{8,-8}),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{1,-8})),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{8,-9})),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{0,-1})),
+ ?line <<>> = binary:part(Simple,{8,0}),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{9,0})),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{-1,0})),
+ ?line badarg = ?MASK_ERROR(binary:part(Simple,{7,2})),
+ ?line <<8>> = binary:part(Simple,{7,1}),
+ ?line random:seed({1271,769940,559934}),
+ ?line random_parts(5000),
+ ok.
+
+
+random_parts(0) ->
+ ok;
+random_parts(N) ->
+ Str = random_string({1,N}),
+ Parts0 = random_parts(10,N),
+ Parts1 = Parts0 ++ [ {X+Y,-Y} || {X,Y} <- Parts0 ],
+ [ begin
+ true = ?MASK_ERROR(binary:part(Str,Z)) =:=
+ ?MASK_ERROR(binref:part(Str,Z)),
+ true = ?MASK_ERROR(binary:part(Str,Z)) =:=
+ ?MASK_ERROR(erlang:binary_part(Str,Z)),
+ true = ?MASK_ERROR(binary:part(Str,Z)) =:=
+ ?MASK_ERROR(binary:part(make_unaligned(Str),Z))
+ end || Z <- Parts1 ],
+ random_parts(N-1).
+
+random_parts(0,_) ->
+ [];
+random_parts(X,N) ->
+ Pos = random:uniform(N),
+ Len = random:uniform((Pos * 12) div 10),
+ [{Pos,Len} | random_parts(X-1,N)].
+
+random_ref_comp(doc) ->
+ ["Test pseudorandomly generated cases against reference imlementation"];
+random_ref_comp(Config) when is_list(Config) ->
+ ?line put(success_counter,0),
+ ?line random:seed({1271,769940,559934}),
+ ?line do_random_match_comp(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_match_comp2(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_match_comp3(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_match_comp4(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_matches_comp(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_matches_comp2(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_matches_comp3(5,{1,40},{30,1000}),
+ ?line erts_debug:set_internal_state(available_internal_state,true),
+ ?line io:format("oldlimit: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,100)]),
+ ?line do_random_match_comp(5000,{1,40},{30,1000}),
+ ?line do_random_matches_comp3(5,{1,40},{30,1000}),
+ ?line io:format("limit was: ~p~n",[ erts_debug:set_internal_state(binary_loop_limit,default)]),
+ ?line erts_debug:set_internal_state(available_internal_state,false),
+ ok.
+
+random_ref_sr_comp(doc) ->
+ ["Test pseudorandomly generated cases against reference imlementation of split and replace"];
+random_ref_sr_comp(Config) when is_list(Config) ->
+ ?line put(success_counter,0),
+ ?line random:seed({1271,769940,559934}),
+ ?line do_random_split_comp(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_replace_comp(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_split_comp2(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ?line do_random_replace_comp2(5000,{1,40},{30,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ok.
+random_ref_fla_comp(doc) ->
+ ["Test pseudorandomly generated cases against reference imlementation of split and replace"];
+random_ref_fla_comp(Config) when is_list(Config) ->
+ ?line put(success_counter,0),
+ ?line random:seed({1271,769940,559934}),
+ ?line do_random_first_comp(5000,{1,1000}),
+ ?line do_random_last_comp(5000,{1,1000}),
+ ?line do_random_at_comp(5000,{1,1000}),
+ io:format("Number of successes: ~p~n",[get(success_counter)]),
+ ok.
+
+do_random_first_comp(0,_) ->
+ ok;
+do_random_first_comp(N,Range) ->
+ S = random_string(Range),
+ A = ?MASK_ERROR(binref:first(S)),
+ B = ?MASK_ERROR(binary:first(S)),
+ C = ?MASK_ERROR(binary:first(make_unaligned(S))),
+ case {(A =:= B), (B =:= C)} of
+ {true,true} ->
+ do_random_first_comp(N-1,Range);
+ _ ->
+ io:format("Failed to pick first of ~s~n",
+ [S]),
+ io:format("A:~p,~nB:~p,~n,C:~p.~n",
+ [A,B,C]),
+ exit(mismatch)
+ end.
+
+do_random_last_comp(0,_) ->
+ ok;
+do_random_last_comp(N,Range) ->
+ S = random_string(Range),
+ A = ?MASK_ERROR(binref:last(S)),
+ B = ?MASK_ERROR(binary:last(S)),
+ C = ?MASK_ERROR(binary:last(make_unaligned(S))),
+ case {(A =:= B), (B =:= C)} of
+ {true,true} ->
+ do_random_last_comp(N-1,Range);
+ _ ->
+ io:format("Failed to pick last of ~s~n",
+ [S]),
+ io:format("A:~p,~nB:~p,~n,C:~p.~n",
+ [A,B,C]),
+ exit(mismatch)
+ end.
+do_random_at_comp(0,_) ->
+ ok;
+do_random_at_comp(N,{Min,Max}=Range) ->
+ S = random_string(Range),
+ XMax = Min + ((Max - Min) * 3) div 4,
+ Pos = random_length({Min,XMax}), %% some out of range
+ A = ?MASK_ERROR(binref:at(S,Pos)),
+ B = ?MASK_ERROR(binary:at(S,Pos)),
+ C = ?MASK_ERROR(binary:at(make_unaligned(S),Pos)),
+ if
+ A =/= badarg ->
+ put(success_counter,get(success_counter)+1);
+ true ->
+ ok
+ end,
+ case {(A =:= B), (B =:= C)} of
+ {true,true} ->
+ do_random_at_comp(N-1,Range);
+ _ ->
+ io:format("Failed to pick last of ~s~n",
+ [S]),
+ io:format("A:~p,~nB:~p,~n,C:~p.~n",
+ [A,B,C]),
+ exit(mismatch)
+ end.
+
+do_random_matches_comp(0,_,_) ->
+ ok;
+do_random_matches_comp(N,NeedleRange,HaystackRange) ->
+ NumNeedles = element(2,HaystackRange) div element(2,NeedleRange),
+ Needles = [random_string(NeedleRange) ||
+ _ <- lists:duplicate(NumNeedles,a)],
+ Haystack = random_string(HaystackRange),
+ true = do_matches_comp(Needles,Haystack),
+ do_random_matches_comp(N-1,NeedleRange,HaystackRange).
+
+do_random_matches_comp2(0,_,_) ->
+ ok;
+do_random_matches_comp2(N,NeedleRange,HaystackRange) ->
+ NumNeedles = element(2,HaystackRange) div element(2,NeedleRange),
+ Haystack = random_string(HaystackRange),
+ Needles = [random_substring(NeedleRange,Haystack) ||
+ _ <- lists:duplicate(NumNeedles,a)],
+ true = do_matches_comp(Needles,Haystack),
+ do_random_matches_comp2(N-1,NeedleRange,HaystackRange).
+
+do_random_matches_comp3(0,_,_) ->
+ ok;
+do_random_matches_comp3(N,NeedleRange,HaystackRange) ->
+ NumNeedles = element(2,HaystackRange) div element(2,NeedleRange),
+ Haystack = random_string(HaystackRange),
+ Needles = [random_substring(NeedleRange,Haystack) ||
+ _ <- lists:duplicate(NumNeedles,a)],
+ RefRes = binref:matches(Haystack,Needles),
+ true = do_matches_comp_loop(10000,Needles,Haystack, RefRes),
+ do_random_matches_comp3(N-1,NeedleRange,HaystackRange).
+
+do_matches_comp_loop(0,_,_,_) ->
+ true;
+do_matches_comp_loop(N, Needles, Haystack0,RR) ->
+ DummySize=N*8,
+ Haystack1 = <<0:DummySize,Haystack0/binary>>,
+ RR1=[{X+N,Y} || {X,Y} <- RR],
+ true = do_matches_comp2(Needles,Haystack1,RR1),
+ Haystack2 = <<Haystack0/binary,Haystack1/binary>>,
+ RR2 = RR ++ [{X2+N+byte_size(Haystack0),Y2} || {X2,Y2} <- RR],
+ true = do_matches_comp2(Needles,Haystack2,RR2),
+ do_matches_comp_loop(N-1, Needles, Haystack0,RR).
+
+
+do_matches_comp2(N,H,A) ->
+ C = ?MASK_ERROR(binary:matches(H,N)),
+ case (A =:= C) of
+ true ->
+ true;
+ _ ->
+ io:format("Failed to match ~p (needle) against ~s (haystack)~n",
+ [N,H]),
+ io:format("A:~p,~n,C:~p.~n",
+ [A,C]),
+ exit(mismatch)
+ end.
+do_matches_comp(N,H) ->
+ A = ?MASK_ERROR(binref:matches(H,N)),
+ B = ?MASK_ERROR(binref:matches(H,binref:compile_pattern(N))),
+ C = ?MASK_ERROR(binary:matches(H,N)),
+ D = ?MASK_ERROR(binary:matches(make_unaligned(H),
+ binary:compile_pattern([make_unaligned2(X) || X <- N]))),
+ if
+ A =/= nomatch ->
+ put(success_counter,get(success_counter)+1);
+ true ->
+ ok
+ end,
+ case {(A =:= B), (B =:= C),(C =:= D)} of
+ {true,true,true} ->
+ true;
+ _ ->
+ io:format("Failed to match ~p (needle) against ~s (haystack)~n",
+ [N,H]),
+ io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p.~n",
+ [A,B,C,D]),
+ exit(mismatch)
+ end.
+
+do_random_match_comp(0,_,_) ->
+ ok;
+do_random_match_comp(N,NeedleRange,HaystackRange) ->
+ Needle = random_string(NeedleRange),
+ Haystack = random_string(HaystackRange),
+ true = do_match_comp(Needle,Haystack),
+ do_random_match_comp(N-1,NeedleRange,HaystackRange).
+
+do_random_match_comp2(0,_,_) ->
+ ok;
+do_random_match_comp2(N,NeedleRange,HaystackRange) ->
+ Haystack = random_string(HaystackRange),
+ Needle = random_substring(NeedleRange,Haystack),
+ true = do_match_comp(Needle,Haystack),
+ do_random_match_comp2(N-1,NeedleRange,HaystackRange).
+
+do_random_match_comp3(0,_,_) ->
+ ok;
+do_random_match_comp3(N,NeedleRange,HaystackRange) ->
+ NumNeedles = element(2,HaystackRange) div element(2,NeedleRange),
+ Haystack = random_string(HaystackRange),
+ Needles = [random_substring(NeedleRange,Haystack) ||
+ _ <- lists:duplicate(NumNeedles,a)],
+ true = do_match_comp3(Needles,Haystack),
+ do_random_match_comp3(N-1,NeedleRange,HaystackRange).
+
+do_random_match_comp4(0,_,_) ->
+ ok;
+do_random_match_comp4(N,NeedleRange,HaystackRange) ->
+ NumNeedles = element(2,HaystackRange) div element(2,NeedleRange),
+ Haystack = random_string(HaystackRange),
+ Needles = [random_string(NeedleRange) ||
+ _ <- lists:duplicate(NumNeedles,a)],
+ true = do_match_comp3(Needles,Haystack),
+ do_random_match_comp4(N-1,NeedleRange,HaystackRange).
+
+do_match_comp(N,H) ->
+ A = ?MASK_ERROR(binref:match(H,N)),
+ B = ?MASK_ERROR(binref:match(H,binref:compile_pattern([N]))),
+ C = ?MASK_ERROR(binary:match(make_unaligned(H),N)),
+ D = ?MASK_ERROR(binary:match(H,binary:compile_pattern([N]))),
+ E = ?MASK_ERROR(binary:match(H,binary:compile_pattern(make_unaligned(N)))),
+ if
+ A =/= nomatch ->
+ put(success_counter,get(success_counter)+1);
+ true ->
+ ok
+ end,
+ case {(A =:= B), (B =:= C),(C =:= D),(D =:= E)} of
+ {true,true,true,true} ->
+ true;
+ _ ->
+ io:format("Failed to match ~s (needle) against ~s (haystack)~n",
+ [N,H]),
+ io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p,E:~p.~n",
+ [A,B,C,D,E]),
+ exit(mismatch)
+ end.
+
+do_match_comp3(N,H) ->
+ A = ?MASK_ERROR(binref:match(H,N)),
+ B = ?MASK_ERROR(binref:match(H,binref:compile_pattern(N))),
+ C = ?MASK_ERROR(binary:match(H,N)),
+ D = ?MASK_ERROR(binary:match(H,binary:compile_pattern(N))),
+ if
+ A =/= nomatch ->
+ put(success_counter,get(success_counter)+1);
+ true ->
+ ok
+ end,
+ case {(A =:= B), (B =:= C),(C =:= D)} of
+ {true,true,true} ->
+ true;
+ _ ->
+ io:format("Failed to match ~s (needle) against ~s (haystack)~n",
+ [N,H]),
+ io:format("A:~p,~nB:~p,~n,C:~p,~n,D:~p.~n",
+ [A,B,C,D]),
+ exit(mismatch)
+ end.
+
+do_random_split_comp(0,_,_) ->
+ ok;
+do_random_split_comp(N,NeedleRange,HaystackRange) ->
+ Haystack = random_string(HaystackRange),
+ Needle = random_substring(NeedleRange,Haystack),
+ true = do_split_comp(Needle,Haystack,[]),
+ true = do_split_comp(Needle,Haystack,[global]),
+ true = do_split_comp(Needle,Haystack,[global,trim]),
+ do_random_split_comp(N-1,NeedleRange,HaystackRange).
+do_random_split_comp2(0,_,_) ->
+ ok;
+do_random_split_comp2(N,NeedleRange,HaystackRange) ->
+ NumNeedles = element(2,HaystackRange) div element(2,NeedleRange),
+ Haystack = random_string(HaystackRange),
+ Needles = [random_substring(NeedleRange,Haystack) ||
+ _ <- lists:duplicate(NumNeedles,a)],
+ true = do_split_comp(Needles,Haystack,[]),
+ true = do_split_comp(Needles,Haystack,[global]),
+ do_random_split_comp2(N-1,NeedleRange,HaystackRange).
+
+do_split_comp(N,H,Opts) ->
+ A = ?MASK_ERROR(binref:split(H,N,Opts)),
+ D = ?MASK_ERROR(binary:split(H,binary:compile_pattern(N),Opts)),
+ if
+ (A =/= [N]) and is_list(A) ->
+ put(success_counter,get(success_counter)+1);
+ true ->
+ ok
+ end,
+ case (A =:= D) of
+ true ->
+ true;
+ _ ->
+ io:format("Failed to split ~n~p ~n(haystack) with ~n~p ~n(needle) "
+ "~nand options ~p~n",
+ [H,N,Opts]),
+ io:format("A:~p,D:~p.~n",
+ [A,D]),
+ exit(mismatch)
+ end.
+
+do_random_replace_comp(0,_,_) ->
+ ok;
+do_random_replace_comp(N,NeedleRange,HaystackRange) ->
+ Haystack = random_string(HaystackRange),
+ Needle = random_substring(NeedleRange,Haystack),
+ Repl = random_string(NeedleRange),
+ Insertat = random_length(NeedleRange), %Sometimes larger than Repl
+ true = do_replace_comp(Needle,Haystack,Repl,[]),
+ true = do_replace_comp(Needle,Haystack,Repl,[global]),
+ true = do_replace_comp(Needle,Haystack,Repl,
+ [global,{insert_replaced,Insertat}]),
+ do_random_replace_comp(N-1,NeedleRange,HaystackRange).
+do_random_replace_comp2(0,_,_) ->
+ ok;
+do_random_replace_comp2(N,NeedleRange,HaystackRange) ->
+ NumNeedles = element(2,HaystackRange) div element(2,NeedleRange),
+ Haystack = random_string(HaystackRange),
+ Needles = [random_substring(NeedleRange,Haystack) ||
+ _ <- lists:duplicate(NumNeedles,a)],
+ Repl = random_string(NeedleRange),
+ Insertat = random_length(NeedleRange), %Sometimes larger than Repl
+ true = do_replace_comp(Needles,Haystack,Repl,[]),
+ true = do_replace_comp(Needles,Haystack,Repl,[global]),
+ true = do_replace_comp(Needles,Haystack,Repl,
+ [global,{insert_replaced,Insertat}]),
+ do_random_replace_comp2(N-1,NeedleRange,HaystackRange).
+
+do_replace_comp(N,H,R,Opts) ->
+ A = ?MASK_ERROR(binref:replace(H,N,R,Opts)),
+ D = ?MASK_ERROR(binary:replace(H,binary:compile_pattern(N),R,Opts)),
+ if
+ (A =/= N) and is_binary(A) ->
+ put(success_counter,get(success_counter)+1);
+ true ->
+ ok
+ end,
+ case (A =:= D) of
+ true ->
+ true;
+ _ ->
+ io:format("Failed to replace ~s (haystack) by ~s (needle) "
+ "inserting ~s (replacement) and options ~p~n",
+ [H,N,R,Opts]),
+ io:format("A:~p,D:~p.~n",
+ [A,D]),
+ exit(mismatch)
+ end.
+
+one_random_number(N) ->
+ M = ((N - 1) rem 10) + 1,
+ element(M,{$0,$1,$2,$3,$4,$5,$6,$7,$8,$9}).
+
+one_random(N) ->
+ M = ((N - 1) rem 68) + 1,
+ element(M,{$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,$�,
+ $�,$�,$0,$1,$2,$3,$4,$5,$6,$7,$8,$9}).
+
+random_number({Min,Max}) -> % Min and Max are *length* of number in
+ % decimal positions
+ X = random:uniform(Max - Min + 1) + Min - 1,
+ list_to_integer([one_random_number(random:uniform(10)) || _ <- lists:seq(1,X)]).
+
+
+random_length({Min,Max}) ->
+ random:uniform(Max - Min + 1) + Min - 1.
+random_string({Min,Max}) ->
+ X = random:uniform(Max - Min + 1) + Min - 1,
+ list_to_binary([one_random(random:uniform(68)) || _ <- lists:seq(1,X)]).
+random_substring({Min,Max},Hay) ->
+ X = random:uniform(Max - Min + 1) + Min - 1,
+ Y = byte_size(Hay),
+ Z = if
+ X > Y -> Y;
+ true -> X
+ end,
+ PMax = Y - Z,
+ Pos = random:uniform(PMax + 1) - 1,
+ <<_:Pos/binary,Res:Z/binary,_/binary>> = Hay,
+ Res.
+
+mask_error({'EXIT',{Err,_}}) ->
+ Err;
+mask_error(Else) ->
+ Else.
+
+make_unaligned(Bin0) when is_binary(Bin0) ->
+ Bin1 = <<0:3,Bin0/binary,31:5>>,
+ Sz = byte_size(Bin0),
+ <<0:3,Bin:Sz/binary,31:5>> = id(Bin1),
+ Bin.
+make_unaligned2(Bin0) when is_binary(Bin0) ->
+ Bin1 = <<31:5,Bin0/binary,0:3>>,
+ Sz = byte_size(Bin0),
+ <<31:5,Bin:Sz/binary,0:3>> = id(Bin1),
+ Bin.
+
+id(I) -> I.
diff --git a/lib/stdlib/test/binref.erl b/lib/stdlib/test/binref.erl
new file mode 100644
index 0000000000..6d96736ef3
--- /dev/null
+++ b/lib/stdlib/test/binref.erl
@@ -0,0 +1,588 @@
+-module(binref).
+
+-export([compile_pattern/1,match/2,match/3,matches/2,matches/3,
+ split/2,split/3,replace/3,replace/4,first/1,last/1,at/2,
+ part/2,part/3,copy/1,copy/2,encode_unsigned/1,encode_unsigned/2,
+ decode_unsigned/1,decode_unsigned/2,referenced_byte_size/1,
+ longest_common_prefix/1,longest_common_suffix/1,bin_to_list/1,
+ bin_to_list/2,bin_to_list/3,list_to_bin/1]).
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% compile_pattern, a dummy
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+compile_pattern(Pattern) when is_binary(Pattern) ->
+ {[Pattern]};
+compile_pattern(Pattern) ->
+ try
+ [ true = is_binary(P) || P <- Pattern ],
+ {Pattern}
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% match and matches
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+match(H,N) ->
+ match(H,N,[]).
+match(Haystack,Needle,Options) when is_binary(Needle) ->
+ match(Haystack,[Needle],Options);
+match(Haystack,{Needles},Options) ->
+ match(Haystack,Needles,Options);
+match(Haystack,Needles,Options) ->
+ try
+ true = is_binary(Haystack) and is_list(Needles), % badarg, not function_clause
+ case get_opts_match(Options,nomatch) of
+ nomatch ->
+ mloop(Haystack,Needles);
+ {A,B} when B > 0 ->
+ <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack,
+ mloop(SubStack,Needles,A,B+A);
+ {A,B} when B < 0 ->
+ Start = A + B,
+ Len = -B,
+ <<_:Start/binary,SubStack:Len/binary,_/binary>> = Haystack,
+ mloop(SubStack,Needles,Start,Len+Start);
+ _ ->
+ nomatch
+ end
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+matches(H,N) ->
+ matches(H,N,[]).
+matches(Haystack,Needle,Options) when is_binary(Needle) ->
+ matches(Haystack,[Needle],Options);
+matches(Haystack,{Needles},Options) ->
+ matches(Haystack,Needles,Options);
+matches(Haystack,Needles,Options) ->
+ try
+ true = is_binary(Haystack) and is_list(Needles), % badarg, not function_clause
+ case get_opts_match(Options,nomatch) of
+ nomatch ->
+ msloop(Haystack,Needles);
+ {A,B} when B > 0 ->
+ <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack,
+ msloop(SubStack,Needles,A,B+A);
+ {A,B} when B < 0 ->
+ Start = A + B,
+ Len = -B,
+ <<_:Start/binary,SubStack:Len/binary,_/binary>> = Haystack,
+ msloop(SubStack,Needles,Start,Len+Start);
+ _ ->
+ []
+ end
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+mloop(Haystack,Needles) ->
+ mloop(Haystack,Needles,0,byte_size(Haystack)).
+
+mloop(_Haystack,_Needles,N,M) when N >= M ->
+ nomatch;
+mloop(Haystack,Needles,N,M) ->
+ case mloop2(Haystack,Needles,N,nomatch) of
+ nomatch ->
+ % Not found
+ <<_:8,NewStack/binary>> = Haystack,
+ mloop(NewStack,Needles,N+1,M);
+ {N,Len} ->
+ {N,Len}
+ end.
+
+msloop(Haystack,Needles) ->
+ msloop(Haystack,Needles,0,byte_size(Haystack)).
+
+msloop(_Haystack,_Needles,N,M) when N >= M ->
+ [];
+msloop(Haystack,Needles,N,M) ->
+ case mloop2(Haystack,Needles,N,nomatch) of
+ nomatch ->
+ % Not found
+ <<_:8,NewStack/binary>> = Haystack,
+ msloop(NewStack,Needles,N+1,M);
+ {N,Len} ->
+ NewN = N+Len,
+ if
+ NewN >= M ->
+ [{N,Len}];
+ true ->
+ <<_:Len/binary,NewStack/binary>> = Haystack,
+ [{N,Len} | msloop(NewStack,Needles,NewN,M)]
+ end
+ end.
+
+mloop2(_Haystack,[],_N,Res) ->
+ Res;
+mloop2(Haystack,[Needle|Tail],N,Candidate) ->
+ NS = byte_size(Needle),
+ case Haystack of
+ <<Needle:NS/binary,_/binary>> ->
+ NewCandidate = case Candidate of
+ nomatch ->
+ {N,NS};
+ {N,ONS} when ONS < NS ->
+ {N,NS};
+ Better ->
+ Better
+ end,
+ mloop2(Haystack,Tail,N,NewCandidate);
+ _ ->
+ mloop2(Haystack,Tail,N,Candidate)
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% split
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+split(H,N) ->
+ split(H,N,[]).
+split(Haystack,{Needles},Options) ->
+ split(Haystack, Needles, Options);
+split(Haystack,Needles0,Options) ->
+ try
+ Needles = if
+ is_list(Needles0) ->
+ Needles0;
+ is_binary(Needles0) ->
+ [Needles0];
+ true ->
+ exit(badtype)
+ end,
+ {Part,Global,Trim} = get_opts_split(Options,{nomatch,false,false}),
+ {Start,End,NewStack} =
+ case Part of
+ nomatch ->
+ {0,byte_size(Haystack),Haystack};
+ {A,B} when B >= 0 ->
+ <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack,
+ {A,A+B,SubStack};
+ {A,B} when B < 0 ->
+ S = A + B,
+ L = -B,
+ <<_:S/binary,SubStack:L/binary,_/binary>> = Haystack,
+ {S,S+L,SubStack}
+ end,
+ MList = if
+ Global ->
+ msloop(NewStack,Needles,Start,End);
+ true ->
+ case mloop(NewStack,Needles,Start,End) of
+ nomatch ->
+ [];
+ X ->
+ [X]
+ end
+ end,
+ do_split(Haystack,MList,0,Trim)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+do_split(H,[],N,true) when N >= byte_size(H) ->
+ [];
+do_split(H,[],N,_) ->
+ [part(H,{N,byte_size(H)-N})];
+do_split(H,[{A,B}|T],N,Trim) ->
+ case part(H,{N,A-N}) of
+ <<>> ->
+ Rest = do_split(H,T,A+B,Trim),
+ case {Trim, Rest} of
+ {true,[]} ->
+ [];
+ _ ->
+ [<<>> | Rest]
+ end;
+ Oth ->
+ [Oth | do_split(H,T,A+B,Trim)]
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% replace
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+replace(H,N,R) ->
+ replace(H,N,R,[]).
+replace(Haystack,{Needles},Replacement,Options) ->
+ replace(Haystack,Needles,Replacement,Options);
+
+replace(Haystack,Needles0,Replacement,Options) ->
+ try
+ Needles = if
+ is_list(Needles0) ->
+ Needles0;
+ is_binary(Needles0) ->
+ [Needles0];
+ true ->
+ exit(badtype)
+ end,
+ true = is_binary(Replacement), % Make badarg instead of function clause
+ {Part,Global,Insert} = get_opts_replace(Options,{nomatch,false,[]}),
+ {Start,End,NewStack} =
+ case Part of
+ nomatch ->
+ {0,byte_size(Haystack),Haystack};
+ {A,B} when B >= 0 ->
+ <<_:A/binary,SubStack:B/binary,_/binary>> = Haystack,
+ {A,A+B,SubStack};
+ {A,B} when B < 0 ->
+ S = A + B,
+ L = -B,
+ <<_:S/binary,SubStack:L/binary,_/binary>> = Haystack,
+ {S,S+L,SubStack}
+ end,
+ MList = if
+ Global ->
+ msloop(NewStack,Needles,Start,End);
+ true ->
+ case mloop(NewStack,Needles,Start,End) of
+ nomatch ->
+ [];
+ X ->
+ [X]
+ end
+ end,
+ ReplList = case Insert of
+ [] ->
+ Replacement;
+ Y when is_integer(Y) ->
+ splitat(Replacement,0,[Y]);
+ Li when is_list(Li) ->
+ splitat(Replacement,0,lists:sort(Li))
+ end,
+ erlang:iolist_to_binary(do_replace(Haystack,MList,ReplList,0))
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+
+do_replace(H,[],_,N) ->
+ [part(H,{N,byte_size(H)-N})];
+do_replace(H,[{A,B}|T],Replacement,N) ->
+ [part(H,{N,A-N}),
+ if
+ is_list(Replacement) ->
+ do_insert(Replacement, part(H,{A,B}));
+ true ->
+ Replacement
+ end
+ | do_replace(H,T,Replacement,A+B)].
+
+do_insert([X],_) ->
+ [X];
+do_insert([H|T],R) ->
+ [H,R|do_insert(T,R)].
+
+splitat(H,N,[]) ->
+ [part(H,{N,byte_size(H)-N})];
+splitat(H,N,[I|T]) ->
+ [part(H,{N,I-N})|splitat(H,I,T)].
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% first, last and at
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+first(Subject) ->
+ try
+ <<A:8,_/binary>> = Subject,
+ A
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+last(Subject) ->
+ try
+ N = byte_size(Subject) - 1,
+ <<_:N/binary,A:8>> = Subject,
+ A
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+at(Subject,X) ->
+ try
+ <<_:X/binary,A:8,_/binary>> = Subject,
+ A
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% bin_to_list
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+bin_to_list(Subject) ->
+ try
+ binary_to_list(Subject)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+bin_to_list(Subject,T) ->
+ try
+ {A0,B0} = T,
+ {A,B} = if
+ B0 < 0 ->
+ {A0+B0,-B0};
+ true ->
+ {A0,B0}
+ end,
+ binary_to_list(Subject,A+1,A+B)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+bin_to_list(Subject,A,B) ->
+ try
+ bin_to_list(Subject,{A,B})
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% list_to_bin
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+list_to_bin(List) ->
+ try
+ erlang:list_to_binary(List)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% longest_common_prefix
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+longest_common_prefix(LB) ->
+ try
+ true = is_list(LB) and (length(LB) > 0), % Make badarg instead of function clause
+ do_longest_common_prefix(LB,0)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+do_longest_common_prefix(LB,X) ->
+ case do_lcp(LB,X,no) of
+ true ->
+ do_longest_common_prefix(LB,X+1);
+ false ->
+ X
+ end.
+do_lcp([],_,_) ->
+ true;
+do_lcp([Bin|_],X,_) when byte_size(Bin) =< X ->
+ false;
+do_lcp([Bin|T],X,no) ->
+ Ch = at(Bin,X),
+ do_lcp(T,X,Ch);
+do_lcp([Bin|T],X,Ch) ->
+ Ch2 = at(Bin,X),
+ if
+ Ch =:= Ch2 ->
+ do_lcp(T,X,Ch);
+ true ->
+ false
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% longest_common_suffix
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+longest_common_suffix(LB) ->
+ try
+ true = is_list(LB) and (length(LB) > 0), % Make badarg instead of function clause
+ do_longest_common_suffix(LB,0)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+do_longest_common_suffix(LB,X) ->
+ case do_lcs(LB,X,no) of
+ true ->
+ do_longest_common_suffix(LB,X+1);
+ false ->
+ X
+ end.
+do_lcs([],_,_) ->
+ true;
+do_lcs([Bin|_],X,_) when byte_size(Bin) =< X ->
+ false;
+do_lcs([Bin|T],X,no) ->
+ Ch = at(Bin,byte_size(Bin) - 1 - X),
+ do_lcs(T,X,Ch);
+do_lcs([Bin|T],X,Ch) ->
+ Ch2 = at(Bin,byte_size(Bin) - 1 - X),
+ if
+ Ch =:= Ch2 ->
+ do_lcs(T,X,Ch);
+ true ->
+ false
+ end.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% part
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+part(Subject,Part) ->
+ try
+ do_part(Subject,Part)
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+part(Subject,Pos,Len) ->
+ part(Subject,{Pos,Len}).
+
+do_part(Bin,{A,B}) when B >= 0 ->
+ <<_:A/binary,Sub:B/binary,_/binary>> = Bin,
+ Sub;
+do_part(Bin,{A,B}) when B < 0 ->
+ S = A + B,
+ L = -B,
+ <<_:S/binary,Sub:L/binary,_/binary>> = Bin,
+ Sub.
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% copy
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+copy(Subject) ->
+ copy(Subject,1).
+copy(Subject,N) ->
+ try
+ true = is_integer(N) and (N >= 0) and is_binary(Subject), % Badarg, not function clause
+ erlang:list_to_binary(lists:duplicate(N,Subject))
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% encode_unsigned
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+encode_unsigned(Unsigned) ->
+ encode_unsigned(Unsigned,big).
+encode_unsigned(Unsigned,Endian) ->
+ try
+ true = is_integer(Unsigned) and (Unsigned >= 0),
+ if
+ Unsigned =:= 0 ->
+ <<0>>;
+ true ->
+ case Endian of
+ big ->
+ list_to_binary(do_encode(Unsigned,[]));
+ little ->
+ list_to_binary(do_encode_r(Unsigned))
+ end
+ end
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+do_encode(0,L) ->
+ L;
+do_encode(N,L) ->
+ Byte = N band 255,
+ NewN = N bsr 8,
+ do_encode(NewN,[Byte|L]).
+
+do_encode_r(0) ->
+ [];
+do_encode_r(N) ->
+ Byte = N band 255,
+ NewN = N bsr 8,
+ [Byte|do_encode_r(NewN)].
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% decode_unsigned
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+decode_unsigned(Subject) ->
+ decode_unsigned(Subject,big).
+
+decode_unsigned(Subject,Endian) ->
+ try
+ true = is_binary(Subject),
+ case Endian of
+ big ->
+ do_decode(Subject,0);
+ little ->
+ do_decode_r(Subject,0)
+ end
+ catch
+ _:_ ->
+ erlang:error(badarg)
+ end.
+
+do_decode(<<>>,N) ->
+ N;
+do_decode(<<X:8,Bin/binary>>,N) ->
+ do_decode(Bin,(N bsl 8) bor X).
+
+do_decode_r(<<>>,N) ->
+ N;
+do_decode_r(Bin,N) ->
+ Sz = byte_size(Bin) - 1,
+ <<NewBin:Sz/binary,X>> = Bin,
+ do_decode_r(NewBin, (N bsl 8) bor X).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% referenced_byte_size cannot
+%% be implemented in pure
+%% erlang
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+referenced_byte_size(Bin) when is_binary(Bin) ->
+ erlang:error(not_implemented);
+referenced_byte_size(_) ->
+ erlang:error(badarg).
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% Simple helper functions
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%% Option "parsing"
+get_opts_match([],Part) ->
+ Part;
+get_opts_match([{scope,{A,B}} | T],_Part) ->
+ get_opts_match(T,{A,B});
+get_opts_match(_,_) ->
+ throw(badopt).
+
+get_opts_split([],{Part,Global,Trim}) ->
+ {Part,Global,Trim};
+get_opts_split([{scope,{A,B}} | T],{_Part,Global,Trim}) ->
+ get_opts_split(T,{{A,B},Global,Trim});
+get_opts_split([global | T],{Part,_Global,Trim}) ->
+ get_opts_split(T,{Part,true,Trim});
+get_opts_split([trim | T],{Part,Global,_Trim}) ->
+ get_opts_split(T,{Part,Global,true});
+get_opts_split(_,_) ->
+ throw(badopt).
+
+get_opts_replace([],{Part,Global,Insert}) ->
+ {Part,Global,Insert};
+get_opts_replace([{scope,{A,B}} | T],{_Part,Global,Insert}) ->
+ get_opts_replace(T,{{A,B},Global,Insert});
+get_opts_replace([global | T],{Part,_Global,Insert}) ->
+ get_opts_replace(T,{Part,true,Insert});
+get_opts_replace([{insert_replaced,N} | T],{Part,Global,_Insert}) ->
+ get_opts_replace(T,{Part,Global,N});
+get_opts_replace(_,_) ->
+ throw(badopt).
diff --git a/lib/stdlib/test/dummy1_h.erl b/lib/stdlib/test/dummy1_h.erl
index 4377d774a3..5b503d5984 100644
--- a/lib/stdlib/test/dummy1_h.erl
+++ b/lib/stdlib/test/dummy1_h.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(dummy1_h).
@@ -21,7 +21,7 @@
%% Test event handler for gen_event_SUITE.erl
-export([init/1, handle_event/2, handle_call/2, handle_info/2,
- terminate/2]).
+ terminate/2, format_status/2]).
init(make_error) ->
{error, my_error};
@@ -67,4 +67,5 @@ terminate(remove_handler, Parent) ->
terminate(_Reason, _State) ->
ok.
-
+format_status(_Opt, [_PDict, _State]) ->
+ "dummy1_h handler state".
diff --git a/lib/stdlib/test/epp_SUITE.erl b/lib/stdlib/test/epp_SUITE.erl
index 4806b5d361..e31dfdd764 100644
--- a/lib/stdlib/test/epp_SUITE.erl
+++ b/lib/stdlib/test/epp_SUITE.erl
@@ -19,12 +19,12 @@
-module(epp_SUITE).
-export([all/1]).
--export([rec_1/1, predef_mac/1,
+-export([rec_1/1, predef_mac/1,
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, overload_mac/1, otp_8388/1, otp_8470/1, otp_8503/1,
- otp_8562/1]).
+ otp_8562/1, otp_8665/1]).
-export([epp_parse_erl_form/2]).
@@ -39,7 +39,7 @@
-define(config(A,B),config(A,B)).
%% -define(t, test_server).
-define(t, io).
-config(priv_dir, _) ->
+config(priv_dir, _) ->
filename:absname("./epp_SUITE_priv");
config(data_dir, _) ->
filename:absname("./epp_SUITE_data").
@@ -64,7 +64,7 @@ all(doc) ->
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,
- overload_mac, otp_8388, otp_8470, otp_8503, otp_8562].
+ overload_mac, otp_8388, otp_8470, otp_8503, otp_8562, otp_8665].
rec_1(doc) ->
["Recursive macros hang or crash epp (OTP-1398)."];
@@ -192,7 +192,7 @@ variable_1(Config) when is_list(Config) ->
%% variable_1.erl includes variable_1_include.hrl and
%% variable_1_include_dir.hrl.
?line {ok, List} = epp:parse_file(File, [], []),
- ?line {value, {attribute,_,a,{value1,value2}}} =
+ ?line {value, {attribute,_,a,{value1,value2}}} =
lists:keysearch(a,3,List),
ok.
@@ -219,13 +219,13 @@ otp_4871(Config) when is_list(Config) ->
%% Testing crash in erl_scan. Unfortunately there currently is
%% no known way to crash erl_scan so it is emulated by killing the
%% file io server. This assumes lots of things about how
- %% the processes are started and how monitors are set up,
+ %% the processes are started and how monitors are set up,
%% so there are some sanity checks before killing.
?line {ok,Epp} = epp:open(File, []),
timer:sleep(1),
?line {current_function,{epp,_,_}} = process_info(Epp, current_function),
?line {monitored_by,[Io]} = process_info(Epp, monitored_by),
- ?line {current_function,{file_io_server,_,_}} =
+ ?line {current_function,{file_io_server,_,_}} =
process_info(Io, current_function),
?line exit(Io, emulate_crash),
timer:sleep(1),
@@ -302,7 +302,7 @@ otp_5362(Config) when is_list(Config) ->
Back_hrl = [<<"
-file(\"">>,File_Back,<<"\", 2).
">>],
-
+
?line ok = file:write_file(File_Back, Back),
?line ok = file:write_file(File_Back_hrl, list_to_binary(Back_hrl)),
@@ -333,7 +333,7 @@ otp_5362(Config) when is_list(Config) ->
?line ok = file:write_file(File_Change, list_to_binary(Change)),
- ?line {ok, change_5362, ChangeWarnings} =
+ ?line {ok, change_5362, ChangeWarnings} =
compile:file(File_Change, Copts),
?line true = message_compare(
[{File_Change,[{{1002,21},erl_lint,{unused_var,'B'}}]},
@@ -441,9 +441,9 @@ skip_header(Config) when is_list(Config) ->
that should be skipped
-module(epp_test_skip_header).
-export([main/1]).
-
+
main(_) -> ?MODULE.
-
+
">>),
?line {ok, Fd} = file:open(File, [read]),
?line io:get_line(Fd, ''),
@@ -494,9 +494,9 @@ otp_7702(Config) when is_list(Config) ->
t() ->
?RECEIVE(foo, bar).">>,
?line ok = file:write_file(File, Contents),
- ?line {ok, file_7702, []} =
+ ?line {ok, file_7702, []} =
compile:file(File, [debug_info,return,{outdir,Dir}]),
-
+
BeamFile = filename:join(Dir, "file_7702.beam"),
{ok, AC} = beam_lib:chunks(BeamFile, [abstract_code]),
@@ -506,7 +506,7 @@ otp_7702(Config) when is_list(Config) ->
L
end,
Forms2 = [erl_lint:modify_line(Form, Fun) || Form <- Forms],
- ?line
+ ?line
[{attribute,1,file,_},
_,
_,
@@ -637,7 +637,7 @@ otp_8130(Config) when is_list(Config) ->
],
?line [] = run(Config, Ts),
-
+
Cs = [{otp_8130_c1,
<<"-define(M1(A), if\n"
"A =:= 1 -> B;\n"
@@ -681,7 +681,7 @@ otp_8130(Config) when is_list(Config) ->
<<"\n-include_lib(\"$apa/foo.hrl\").\n">>,
{errors,[{{2,2},epp,{include,lib,"$apa/foo.hrl"}}],[]}},
-
+
{otp_8130_c9,
<<"-define(S, ?S).\n"
"t() -> ?S.\n">>,
@@ -775,7 +775,7 @@ otp_8130(Config) when is_list(Config) ->
?line Dir = ?config(priv_dir, Config),
?line File = filename:join(Dir, "otp_8130.erl"),
- ?line ok = file:write_file(File,
+ ?line ok = file:write_file(File,
"-module(otp_8130).\n"
"-define(a, 3.14).\n"
"t() -> ?a.\n"),
@@ -788,7 +788,7 @@ otp_8130(Config) when is_list(Config) ->
?line {eof,_} = epp:scan_erl_form(Epp),
?line ['BASE_MODULE','BASE_MODULE_STRING','BEAM','FILE','LINE',
'MACHINE','MODULE','MODULE_STRING',a] = macs(Epp),
- ?line epp:close(Epp),
+ ?line epp:close(Epp),
%% escript
ModuleStr = "any_name",
@@ -815,7 +815,7 @@ otp_8130(Config) when is_list(Config) ->
PreDefMacros = [{a,1},a],
?line {error,{redefine,a}} = epp:open(File, [], PreDefMacros)
end(),
-
+
?line {error,enoent} = epp:open("no such file", []),
?line {error,enoent} = epp:parse_file("no such file", [], []),
@@ -941,7 +941,7 @@ ifdef(Config) ->
<<"\n-if.\n"
"-endif.\n">>,
{errors,[{{2,2},epp,{'NYI','if'}}],[]}},
-
+
{define_c7,
<<"-ifndef(a).\n"
"-elif.\n"
@@ -1197,6 +1197,18 @@ otp_8562(Config) when is_list(Config) ->
?line [] = compile(Config, Cs),
ok.
+otp_8665(doc) ->
+ ["OTP-8665. Bugfix premature end."];
+otp_8665(suite) ->
+ [];
+otp_8665(Config) when is_list(Config) ->
+ Cs = [{otp_8562,
+ <<"-define(A, a)\n">>,
+ {errors,[{{1,54},epp,premature_end}],[]}}
+ ],
+ ?line [] = compile(Config, Cs),
+ ok.
+
check(Config, Tests) ->
eval_tests(Config, fun check_test/2, Tests).
@@ -1213,7 +1225,7 @@ eval_tests(Config, Fun, Tests) ->
case message_compare(E, Return) of
true ->
BadL;
- false ->
+ false ->
?t:format("~nTest ~p failed. Expected~n ~p~n"
"but got~n ~p~n", [N, E, Return]),
fail()
@@ -1228,9 +1240,9 @@ check_test(Config, Test) ->
?line File = filename:join(PrivDir, Filename),
?line ok = file:write_file(File, Test),
?line case epp:parse_file(File, [PrivDir], []) of
- {ok,Forms} ->
+ {ok,Forms} ->
[E || E={error,_} <- Forms];
- {error,Error} ->
+ {error,Error} ->
Error
end.
@@ -1245,7 +1257,7 @@ compile_test(Config, Test0) ->
{ok, Ws} -> warnings(File, Ws);
Else -> Else
end.
-
+
warnings(File, Ws) ->
case lists:append([W || {F, W} <- Ws, F =:= File]) of
[] -> [];
@@ -1289,7 +1301,7 @@ message_compare(T, T) ->
message_compare(T1, T2) ->
ln(T1) =:= T2.
-%% Replaces locations like {Line,Column} with Line.
+%% Replaces locations like {Line,Column} with Line.
ln({warnings,L}) ->
{warnings,ln0(L)};
ln({errors,EL,WL}) ->
diff --git a/lib/stdlib/test/erl_lint_SUITE.erl b/lib/stdlib/test/erl_lint_SUITE.erl
index 8581b496aa..01f494ee38 100644
--- a/lib/stdlib/test/erl_lint_SUITE.erl
+++ b/lib/stdlib/test/erl_lint_SUITE.erl
@@ -1784,6 +1784,9 @@ otp_5362(Config) when is_list(Config) ->
{15,erl_lint,{undefined_field,ok,nix}},
{16,erl_lint,{field_name_is_variable,ok,'Var'}}]}},
+ %% Nowarn_bif_clash has changed behaviour as local functions
+ %% nowdays supersede auto-imported BIFs, why nowarn_bif_clash in itself generates an error
+ %% (OTP-8579) /PaN
{otp_5362_4,
<<"-compile(nowarn_deprecated_function).
-compile(nowarn_bif_clash).
@@ -1795,9 +1798,8 @@ otp_5362(Config) when is_list(Config) ->
warn_deprecated_function,
warn_bif_clash]},
{error,
- [{5,erl_lint,{call_to_redefined_bif,{spawn,1}}}],
- [{3,erl_lint,{redefine_bif,{spawn,1}}},
- {4,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2},
+ [{5,erl_lint,{call_to_redefined_old_bif,{spawn,1}}}],
+ [{4,erl_lint,{deprecated,{erlang,hash,2},{erlang,phash2,2},
"in a future release"}}]}},
{otp_5362_5,
@@ -1808,8 +1810,8 @@ otp_5362(Config) when is_list(Config) ->
spawn(A).
">>,
{[nowarn_unused_function]},
- {warnings,
- [{3,erl_lint,{redefine_bif,{spawn,1}}}]}},
+ {errors,
+ [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
%% The special nowarn_X are not affected by general warn_X.
{otp_5362_6,
@@ -1822,8 +1824,8 @@ otp_5362(Config) when is_list(Config) ->
{[nowarn_unused_function,
warn_deprecated_function,
warn_bif_clash]},
- {warnings,
- [{3,erl_lint,{redefine_bif,{spawn,1}}}]}},
+ {errors,
+ [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}},
{otp_5362_7,
<<"-export([spawn/1]).
@@ -1838,7 +1840,9 @@ otp_5362(Config) when is_list(Config) ->
spawn(A).
">>,
{[nowarn_unused_function]},
- {error,[{4,erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}],
+ {error,[{3,erl_lint,disallowed_nowarn_bif_clash},
+ {4,erl_lint,disallowed_nowarn_bif_clash},
+ {4,erl_lint,{bad_nowarn_bif_clash,{spawn,2}}}],
[{5,erl_lint,{bad_nowarn_deprecated_function,{3,hash,-1}}},
{5,erl_lint,{bad_nowarn_deprecated_function,{erlang,hash,-1}}},
{5,erl_lint,{bad_nowarn_deprecated_function,{{a,b,c},hash,-1}}}]}
@@ -1865,7 +1869,21 @@ otp_5362(Config) when is_list(Config) ->
t() -> #a{}.
">>,
{[]},
- []}
+ []},
+
+ {otp_5362_10,
+ <<"-compile({nowarn_deprecated_function,{erlang,hash,2}}).
+ -compile({nowarn_bif_clash,{spawn,1}}).
+ -import(x,[spawn/1]).
+ spin(A) ->
+ erlang:hash(A, 3000),
+ spawn(A).
+ ">>,
+ {[nowarn_unused_function,
+ warn_deprecated_function,
+ warn_bif_clash]},
+ {errors,
+ [{2,erl_lint,disallowed_nowarn_bif_clash}],[]}}
],
@@ -2389,9 +2407,9 @@ bif_clash(Config) when is_list(Config) ->
N.
">>,
[],
- {errors,[{2,erl_lint,{call_to_redefined_bif,{size,1}}}],[]}},
+ {errors,[{2,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}},
- %% Verify that (some) warnings can be turned off.
+ %% Verify that warnings can not be turned off in the old way.
{clash2,
<<"-export([t/1,size/1]).
t(X) ->
@@ -2400,17 +2418,189 @@ bif_clash(Config) when is_list(Config) ->
size({N,_}) ->
N.
- %% My own abs/1 function works on lists too.
- %% Unfortunately, it is not exported, so there will
- %% be a warning that can't be turned off.
+ %% My own abs/1 function works on lists too. From R14 this really works.
abs([H|T]) when $a =< H, H =< $z -> [H-($a-$A)|abs(T)];
abs([H|T]) -> [H|abs(T)];
abs([]) -> [];
abs(X) -> erlang:abs(X).
">>,
- {[nowarn_bif_clash]},
- {warnings,[{11,erl_lint,{redefine_bif,{abs,1}}},
- {11,erl_lint,{unused_function,{abs,1}}}]}}],
+ {[nowarn_unused_function,nowarn_bif_clash]},
+ {errors,[{erl_lint,disallowed_nowarn_bif_clash}],[]}},
+ %% As long as noone calls an overridden BIF, it's totally OK
+ {clash3,
+ <<"-export([size/1]).
+ size({N,_}) ->
+ N;
+ size(X) ->
+ erlang:size(X).
+ ">>,
+ [],
+ []},
+ %% But this is totally wrong - meaning of the program changed in R14, so this is an error
+ {clash4,
+ <<"-export([size/1]).
+ size({N,_}) ->
+ N;
+ size(X) ->
+ size(X).
+ ">>,
+ [],
+ {errors,[{5,erl_lint,{call_to_redefined_old_bif,{size,1}}}],[]}},
+ %% For a post R14 bif, its only a warning
+ {clash5,
+ <<"-export([binary_part/2]).
+ binary_part({B,_},{X,Y}) ->
+ binary_part(B,{X,Y});
+ binary_part(B,{X,Y}) ->
+ binary:part(B,X,Y).
+ ">>,
+ [],
+ {warnings,[{3,erl_lint,{call_to_redefined_bif,{binary_part,2}}}]}},
+ %% If you really mean to call yourself here, you can "unimport" size/1
+ {clash6,
+ <<"-export([size/1]).
+ -compile({no_auto_import,[size/1]}).
+ size([]) ->
+ 0;
+ size({N,_}) ->
+ N;
+ size([_|T]) ->
+ 1+size(T).
+ ">>,
+ [],
+ []},
+ %% Same for the post R14 autoimport warning
+ {clash7,
+ <<"-export([binary_part/2]).
+ -compile({no_auto_import,[binary_part/2]}).
+ binary_part({B,_},{X,Y}) ->
+ binary_part(B,{X,Y});
+ binary_part(B,{X,Y}) ->
+ binary:part(B,X,Y).
+ ">>,
+ [],
+ []},
+ %% but this doesn't mean the local function is allowed in a guard...
+ {clash8,
+ <<"-export([x/1]).
+ -compile({no_auto_import,[binary_part/2]}).
+ x(X) when binary_part(X,{1,2}) =:= <<1,2>> ->
+ hej.
+ binary_part({B,_},{X,Y}) ->
+ binary_part(B,{X,Y});
+ binary_part(B,{X,Y}) ->
+ binary:part(B,X,Y).
+ ">>,
+ [],
+ {errors,[{3,erl_lint,illegal_guard_expr}],[]}},
+ %% no_auto_import is not like nowarn_bif_clash, it actually removes the autoimport
+ {clash9,
+ <<"-export([x/1]).
+ -compile({no_auto_import,[binary_part/2]}).
+ x(X) ->
+ binary_part(X,{1,2}) =:= <<1,2>>.
+ ">>,
+ [],
+ {errors,[{4,erl_lint,{undefined_function,{binary_part,2}}}],[]}},
+ %% but we could import it again...
+ {clash10,
+ <<"-export([x/1]).
+ -compile({no_auto_import,[binary_part/2]}).
+ -import(erlang,[binary_part/2]).
+ x(X) ->
+ binary_part(X,{1,2}) =:= <<1,2>>.
+ ">>,
+ [],
+ []},
+ %% and actually use it in a guard...
+ {clash11,
+ <<"-export([x/1]).
+ -compile({no_auto_import,[binary_part/2]}).
+ -import(erlang,[binary_part/2]).
+ x(X) when binary_part(X,{0,1}) =:= <<0>> ->
+ binary_part(X,{1,2}) =:= <<1,2>>.
+ ">>,
+ [],
+ []},
+ %% but for non-obvious historical reasons, imported functions cannot be used in
+ %% fun construction without the module name...
+ {clash12,
+ <<"-export([x/1]).
+ -compile({no_auto_import,[binary_part/2]}).
+ -import(erlang,[binary_part/2]).
+ x(X) when binary_part(X,{0,1}) =:= <<0>> ->
+ binary_part(X,{1,2}) =:= fun binary_part/2.
+ ">>,
+ [],
+ {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}},
+ %% Not from erlang and not from anywhere else
+ {clash13,
+ <<"-export([x/1]).
+ -compile({no_auto_import,[binary_part/2]}).
+ -import(x,[binary_part/2]).
+ x(X) ->
+ binary_part(X,{1,2}) =:= fun binary_part/2.
+ ">>,
+ [],
+ {errors,[{5,erl_lint,{undefined_function,{binary_part,2}}}],[]}},
+ %% ...while real auto-import is OK.
+ {clash14,
+ <<"-export([x/1]).
+ x(X) when binary_part(X,{0,1}) =:= <<0>> ->
+ binary_part(X,{1,2}) =:= fun binary_part/2.
+ ">>,
+ [],
+ []},
+ %% Import directive clashing with old bif is an error, regardless of if it's called or not
+ {clash15,
+ <<"-export([x/1]).
+ -import(x,[abs/1]).
+ x(X) ->
+ binary_part(X,{1,2}).
+ ">>,
+ [],
+ {errors,[{2,erl_lint,{redefine_old_bif_import,{abs,1}}}],[]}},
+ %% For a new BIF, it's only a warning
+ {clash16,
+ <<"-export([x/1]).
+ -import(x,[binary_part/3]).
+ x(X) ->
+ abs(X).
+ ">>,
+ [],
+ {warnings,[{2,erl_lint,{redefine_bif_import,{binary_part,3}}}]}},
+ %% And, you cannot redefine already imported things that aren't auto-imported
+ {clash17,
+ <<"-export([x/1]).
+ -import(x,[binary_port/3]).
+ -import(y,[binary_port/3]).
+ x(X) ->
+ abs(X).
+ ">>,
+ [],
+ {errors,[{3,erl_lint,{redefine_import,{{binary_port,3},x}}}],[]}},
+ %% Not with local functions either
+ {clash18,
+ <<"-export([x/1]).
+ -import(x,[binary_port/3]).
+ binary_port(A,B,C) ->
+ binary_part(A,B,C).
+ x(X) ->
+ abs(X).
+ ">>,
+ [],
+ {errors,[{3,erl_lint,{define_import,{binary_port,3}}}],[]}},
+ %% Like clash8: Dont accept a guard if it's explicitly module-name called either
+ {clash19,
+ <<"-export([binary_port/3]).
+ -compile({no_auto_import,[binary_part/3]}).
+ -import(x,[binary_part/3]).
+ binary_port(A,B,C) when x:binary_part(A,B,C) ->
+ binary_part(A,B,C+1).
+ ">>,
+ [],
+ {errors,[{4,erl_lint,illegal_guard_expr}],[]}}
+ ],
?line [] = run(Config, Ts),
ok.
diff --git a/lib/stdlib/test/erl_pp_SUITE.erl b/lib/stdlib/test/erl_pp_SUITE.erl
index 66730b7b94..c57541fba9 100644
--- a/lib/stdlib/test/erl_pp_SUITE.erl
+++ b/lib/stdlib/test/erl_pp_SUITE.erl
@@ -46,7 +46,7 @@
neg_indent/1,
tickets/1,
otp_6321/1, otp_6911/1, otp_6914/1, otp_8150/1, otp_8238/1,
- otp_8473/1, otp_8522/1, otp_8567/1]).
+ otp_8473/1, otp_8522/1, otp_8567/1, otp_8664/1]).
%% Internal export.
-export([ehook/6]).
@@ -765,7 +765,7 @@ neg_indent(Config) when is_list(Config) ->
tickets(suite) ->
[otp_6321, otp_6911, otp_6914, otp_8150, otp_8238, otp_8473, otp_8522,
- otp_8567].
+ otp_8567, otp_8664].
otp_6321(doc) ->
"OTP_6321. Bug fix of exprs().";
@@ -995,6 +995,38 @@ otp_8567(Config) when is_list(Config) ->
ok.
+otp_8664(doc) ->
+ "OTP_8664. Types with integer expressions.";
+otp_8664(suite) -> [];
+otp_8664(Config) when is_list(Config) ->
+ FileName = filename('otp_8664.erl', Config),
+ C1 = <<"-module(otp_8664).\n"
+ "-export([t/0]).\n"
+ "-define(A, -3).\n"
+ "-define(B, (?A*(-1 band (((2)))))).\n"
+ "-type t1() :: ?B | ?A.\n"
+ "-type t2() :: ?B-1 .. -?B.\n"
+ "-type t3() :: 9 band (8 - 3) | 1+2 | 5 band 3.\n"
+ "-type b1() :: <<_:_*(3-(-1))>>\n"
+ " | <<_:(-(?B))>>\n"
+ " | <<_:4>>.\n"
+ "-type u() :: 1 .. 2 | 3.. 4 | (8-3) ..6 | 5+0..6.\n"
+ "-type t() :: t1() | t2() | t3() | b1() | u().\n"
+ "-spec t() -> t().\n"
+ "t() -> 3.\n">>,
+ ?line ok = file:write_file(FileName, C1),
+ ?line {ok, _, []} = compile:file(FileName, [return]),
+
+ C2 = <<"-module(otp_8664).\n"
+ "-export([t/0]).\n"
+ "-spec t() -> 9 and 4.\n"
+ "t() -> 0.\n">>,
+ ?line ok = file:write_file(FileName, C2),
+ ?line {error,[{_,[{3,erl_lint,{type_syntax,integer}}]}],_} =
+ compile:file(FileName, [return]),
+
+ ok.
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
compile(Config, Tests) ->
diff --git a/lib/stdlib/test/erl_scan_SUITE.erl b/lib/stdlib/test/erl_scan_SUITE.erl
index afeb67eeb1..32eb97bc92 100644
--- a/lib/stdlib/test/erl_scan_SUITE.erl
+++ b/lib/stdlib/test/erl_scan_SUITE.erl
@@ -185,7 +185,7 @@ reserved_words() ->
'andalso', 'orelse', 'end', 'fun', 'if', 'let', 'of',
'query', 'receive', 'when', 'bnot', 'not', 'div',
'rem', 'band', 'and', 'bor', 'bxor', 'bsl', 'bsr',
- 'or', 'xor'] ,
+ 'or', 'xor'],
[begin
?line {RW, true} = {RW, erl_scan:reserved_word(RW)},
S = atom_to_list(RW),
@@ -244,6 +244,9 @@ punctuations() ->
{'\\',1},{'^',1},{'`',1},{'~',1}],
?line test_string("#&*+/:<>?@\\^`~", PTs2),
+ ?line test_string(".. ", [{'..',1}]),
+ ?line test("1 .. 2"),
+ ?line test_string("...", [{'...',1}]),
ok.
comments() ->
diff --git a/lib/stdlib/test/gen_event_SUITE.erl b/lib/stdlib/test/gen_event_SUITE.erl
index 8cbffaca56..4f7de451e3 100644
--- a/lib/stdlib/test/gen_event_SUITE.erl
+++ b/lib/stdlib/test/gen_event_SUITE.erl
@@ -23,9 +23,11 @@
-export([all/1]).
-export([start/1, test_all/1, add_handler/1, add_sup_handler/1,
delete_handler/1, swap_handler/1, swap_sup_handler/1,
- notify/1, sync_notify/1, call/1, info/1, hibernate/1]).
+ notify/1, sync_notify/1, call/1, info/1, hibernate/1,
+ call_format_status/1, error_format_status/1]).
-all(suite) -> {req, [stdlib], [start, test_all, hibernate]}.
+all(suite) -> {req, [stdlib], [start, test_all, hibernate,
+ call_format_status, error_format_status]}.
%% --------------------------------------
%% Start an event manager.
@@ -844,3 +846,56 @@ info(Config) when is_list(Config) ->
?line ok = gen_event:stop(my_dummy_handler),
ok.
+
+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_event:start({local, my_dummy_handler}),
+ %% State here intentionally differs from what we expect from format_status
+ State = self(),
+ FmtState = "dummy1_h handler state",
+ ?line ok = gen_event:add_handler(my_dummy_handler, dummy1_h, [State]),
+ ?line Status1 = sys:get_status(Pid),
+ ?line Status2 = sys:get_status(Pid, 5000),
+ ?line ok = gen_event:stop(Pid),
+ ?line {status, Pid, _, [_, _, Pid, [], Data1]} = Status1,
+ ?line HandlerInfo1 = proplists:get_value(items, Data1),
+ ?line {"Installed handlers", [{_,dummy1_h,_,FmtState,_}]} = HandlerInfo1,
+ ?line {status, Pid, _, [_, _, Pid, [], Data2]} = Status2,
+ ?line HandlerInfo2 = proplists:get_value(items, Data2),
+ ?line {"Installed handlers", [{_,dummy1_h,_,FmtState,_}]} = HandlerInfo2,
+ ok.
+
+error_format_status(suite) ->
+ [];
+error_format_status(doc) ->
+ ["Test that a handler error calls format_status/2"];
+error_format_status(Config) when is_list(Config) ->
+ ?line error_logger_forwarder:register(),
+ OldFl = process_flag(trap_exit, true),
+ State = self(),
+ ?line {ok, Pid} = gen_event:start({local, my_dummy_handler}),
+ ?line ok = gen_event:add_sup_handler(my_dummy_handler, dummy1_h, [State]),
+ ?line ok = gen_event:notify(my_dummy_handler, do_crash),
+ ?line receive
+ {gen_event_EXIT,dummy1_h,{'EXIT',_}} -> ok
+ after 5000 ->
+ ?t:fail(exit_gen_event)
+ end,
+ FmtState = "dummy1_h handler state",
+ receive
+ {error,_GroupLeader, {Pid,
+ "** gen_event handler"++_,
+ [dummy1_h,my_dummy_handler,do_crash,
+ FmtState, _]}} ->
+ ok;
+ Other ->
+ ?line io:format("Unexpected: ~p", [Other]),
+ ?line ?t:fail()
+ end,
+ ?t:messages_get(),
+ ?line ok = gen_event:stop(Pid),
+ process_flag(trap_exit, OldFl),
+ ok.
diff --git a/lib/stdlib/test/gen_fsm_SUITE.erl b/lib/stdlib/test/gen_fsm_SUITE.erl
index 23c1d9a193..dd120f8c05 100644
--- a/lib/stdlib/test/gen_fsm_SUITE.erl
+++ b/lib/stdlib/test/gen_fsm_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_fsm_SUITE).
@@ -30,7 +30,7 @@
-export([shutdown/1]).
--export([sys/1, sys1/1, call_format_status/1]).
+-export([sys/1, sys1/1, call_format_status/1, error_format_status/1]).
-export([hibernate/1,hiber_idle/3,hiber_wakeup/3,hiber_idle/2,hiber_wakeup/2]).
@@ -305,7 +305,7 @@ shutdown(Config) when is_list(Config) ->
ok.
-sys(suite) -> [sys1, call_format_status].
+sys(suite) -> [sys1, call_format_status, error_format_status].
sys1(Config) when is_list(Config) ->
?line {ok, Pid} =
@@ -320,10 +320,53 @@ sys1(Config) when is_list(Config) ->
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 {status, Pid, _Mod, [_PDict, running, _, _, Data]} = Status,
?line [format_status_called | _] = lists:reverse(Data),
- ?line stop_it(Pid).
+ ?line stop_it(Pid),
+
+ %% check that format_status can handle a name being an atom (pid is
+ %% already checked by the previous test)
+ ?line {ok, Pid2} = gen_fsm:start({local, gfsm}, gen_fsm_SUITE, [], []),
+ ?line Status2 = sys:get_status(gfsm),
+ ?line {status, Pid2, _Mod, [_PDict2, running, _, _, Data2]} = Status2,
+ ?line [format_status_called | _] = lists:reverse(Data2),
+ ?line stop_it(Pid2),
+ %% check that format_status can handle a name being a term other than a
+ %% pid or atom
+ GlobalName1 = {global, "CallFormatStatus"},
+ ?line {ok, Pid3} = gen_fsm:start(GlobalName1, gen_fsm_SUITE, [], []),
+ ?line Status3 = sys:get_status(GlobalName1),
+ ?line {status, Pid3, _Mod, [_PDict3, running, _, _, Data3]} = Status3,
+ ?line [format_status_called | _] = lists:reverse(Data3),
+ ?line stop_it(Pid3),
+ GlobalName2 = {global, {name, "term"}},
+ ?line {ok, Pid4} = gen_fsm:start(GlobalName2, gen_fsm_SUITE, [], []),
+ ?line Status4 = sys:get_status(GlobalName2),
+ ?line {status, Pid4, _Mod, [_PDict4, running, _, _, Data4]} = Status4,
+ ?line [format_status_called | _] = lists:reverse(Data4),
+ ?line stop_it(Pid4).
+
+error_format_status(Config) when is_list(Config) ->
+ ?line error_logger_forwarder:register(),
+ OldFl = process_flag(trap_exit, true),
+ StateData = "called format_status",
+ ?line {ok, Pid} = gen_fsm:start(gen_fsm_SUITE, {state_data, StateData}, []),
+ %% bad return value in the gen_fsm loop
+ ?line {'EXIT',{{bad_return_value, badreturn},_}} =
+ (catch gen_fsm:sync_send_event(Pid, badreturn)),
+ receive
+ {error,_GroupLeader,{Pid,
+ "** State machine"++_,
+ [Pid,{_,_,badreturn},idle,StateData,_]}} ->
+ ok;
+ Other ->
+ ?line io:format("Unexpected: ~p", [Other]),
+ ?line ?t:fail()
+ end,
+ ?t:messages_get(),
+ process_flag(trap_exit, OldFl),
+ ok.
%% Hibernation
hibernate(suite) -> [];
@@ -704,6 +747,8 @@ init(hiber) ->
{ok, hiber_idle, []};
init(hiber_now) ->
{ok, hiber_idle, [], hibernate};
+init({state_data, StateData}) ->
+ {ok, idle, StateData};
init(_) ->
{ok, idle, state_data}.
@@ -844,5 +889,7 @@ handle_sync_event(stop_shutdown_reason, _From, _State, Data) ->
handle_sync_event({get, _Pid}, _From, State, Data) ->
{reply, {state, State, Data}, State, Data}.
-format_status(_Opt, [_Pdict, _StateData]) ->
+format_status(terminate, [_Pdict, StateData]) ->
+ StateData;
+format_status(normal, [_Pdict, _StateData]) ->
[format_status_called].
diff --git a/lib/stdlib/test/gen_server_SUITE.erl b/lib/stdlib/test/gen_server_SUITE.erl
index 6efdce78a1..99388ba2e3 100644
--- a/lib/stdlib/test/gen_server_SUITE.erl
+++ b/lib/stdlib/test/gen_server_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_server_SUITE).
@@ -30,7 +30,8 @@
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, call_format_status/1
+ otp_5854/1, hibernate/1, otp_7669/1, call_format_status/1,
+ error_format_status/1, call_with_huge_message_queue/1
]).
% spawn export
@@ -51,7 +52,9 @@ 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, call_format_status].
+ otp_5854, hibernate, otp_7669,
+ call_format_status, error_format_status,
+ call_with_huge_message_queue].
-define(default_timeout, ?t:minutes(1)).
@@ -895,15 +898,105 @@ 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, [], []),
+ ?MODULE, [], []),
?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),
+
+ %% check that format_status can handle a name being a pid (atom is
+ %% already checked by the previous test)
+ ?line {ok, Pid3} = gen_server:start_link(gen_server_SUITE, [], []),
+ ?line Status3 = sys:get_status(Pid3),
+ ?line {status, Pid3, _Mod, [_PDict3, running, _Parent, _, Data3]} = Status3,
+ ?line [format_status_called | _] = lists:reverse(Data3),
+
+ %% check that format_status can handle a name being a term other than a
+ %% pid or atom
+ GlobalName1 = {global, "CallFormatStatus"},
+ ?line {ok, Pid4} = gen_server:start_link(GlobalName1,
+ gen_server_SUITE, [], []),
+ ?line Status4 = sys:get_status(Pid4),
+ ?line {status, Pid4, _Mod, [_PDict4, running, _Parent, _, Data4]} = Status4,
+ ?line [format_status_called | _] = lists:reverse(Data4),
+ GlobalName2 = {global, {name, "term"}},
+ ?line {ok, Pid5} = gen_server:start_link(GlobalName2,
+ gen_server_SUITE, [], []),
+ ?line Status5 = sys:get_status(GlobalName2),
+ ?line {status, Pid5, _Mod, [_PDict5, running, _Parent, _, Data5]} = Status5,
+ ?line [format_status_called | _] = lists:reverse(Data5),
+ ok.
+
+%% Verify that error termination correctly calls our format_status/2 fun
+%%
+error_format_status(suite) ->
+ [];
+error_format_status(doc) ->
+ ["Test that an error termination calls format_status/2"];
+error_format_status(Config) when is_list(Config) ->
+ ?line error_logger_forwarder:register(),
+ OldFl = process_flag(trap_exit, true),
+ State = "called format_status",
+ ?line {ok, Pid} = gen_server:start_link(?MODULE, {state, State}, []),
+ ?line {'EXIT',{crashed,_}} = (catch gen_server:call(Pid, crash)),
+ receive
+ {'EXIT', Pid, crashed} ->
+ ok
+ end,
+ receive
+ {error,_GroupLeader,{Pid,
+ "** Generic server"++_,
+ [Pid,crash,State,crashed]}} ->
+ ok;
+ Other ->
+ ?line io:format("Unexpected: ~p", [Other]),
+ ?line ?t:fail()
+ end,
+ ?t:messages_get(),
+ process_flag(trap_exit, OldFl),
+ ok.
+
+%% Test that the time for a huge message queue is not
+%% significantly slower than with an empty message queue.
+call_with_huge_message_queue(Config) when is_list(Config) ->
+ ?line Pid = spawn_link(fun echo_loop/0),
+
+ ?line {Time,ok} = tc(fun() -> calls(10, Pid) end),
+
+ ?line [self() ! {msg,N} || N <- lists:seq(1, 500000)],
+ erlang:garbage_collect(),
+ ?line {NewTime,ok} = tc(fun() -> calls(10, Pid) end),
+ io:format("Time for empty message queue: ~p", [Time]),
+ io:format("Time for huge message queue: ~p", [NewTime]),
+
+ case (NewTime+1) / (Time+1) of
+ Q when Q < 10 ->
+ ok;
+ Q ->
+ io:format("Q = ~p", [Q]),
+ ?line ?t:fail()
+ end,
ok.
+calls(0, _) -> ok;
+calls(N, Pid) ->
+ {ultimate_answer,42} = call(Pid, {ultimate_answer,42}),
+ calls(N-1, Pid).
+
+call(Pid, Msg) ->
+ gen_server:call(Pid, Msg, infinity).
+
+tc(Fun) ->
+ timer:tc(erlang, apply, [Fun,[]]).
+
+echo_loop() ->
+ receive
+ {'$gen_call',{Pid,Ref},Msg} ->
+ Pid ! {Ref,Msg},
+ echo_loop()
+ end.
%%--------------------------------------------------------------
%% Help functions to spec_init_*
@@ -1064,5 +1157,7 @@ terminate({From, stopped_info}, _State) ->
terminate(_Reason, _State) ->
ok.
-format_status(_Opt, [_PDict, _State]) ->
- [format_status_called].
+format_status(terminate, [_PDict, State]) ->
+ State;
+format_status(normal, [_PDict, _State]) ->
+ format_status_called.
diff --git a/lib/stdlib/test/io_proto_SUITE.erl b/lib/stdlib/test/io_proto_SUITE.erl
index 93159fbd5b..d9672a8c7b 100644
--- a/lib/stdlib/test/io_proto_SUITE.erl
+++ b/lib/stdlib/test/io_proto_SUITE.erl
@@ -17,6 +17,7 @@
%% %CopyrightEnd%
%%
-module(io_proto_SUITE).
+-compile(r12).
-export([all/1]).
diff --git a/lib/stdlib/test/qlc_SUITE.erl b/lib/stdlib/test/qlc_SUITE.erl
index ff11ebc6bf..e21de8770a 100644
--- a/lib/stdlib/test/qlc_SUITE.erl
+++ b/lib/stdlib/test/qlc_SUITE.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%
%%
%%%----------------------------------------------------------------
%%% Purpose:Test Suite for the 'qlc' module.
%%%-----------------------------------------------------------------
-module(qlc_SUITE).
+-compile(r12).
-define(QLC, qlc).
-define(QLCs, "qlc").
@@ -3183,7 +3184,9 @@ lookup2(Config) when is_list(Config) ->
[] = qlc:e(Q),
false = lookup_keys(Q)
end, [{1,b},{2,3}])">>,
- {warnings,[{{3,48},qlc,nomatch_filter}]}},
+ {warnings,[{2,sys_core_fold,nomatch_guard},
+ {3,qlc,nomatch_filter},
+ {3,sys_core_fold,{eval_failure,badarg}}]}},
<<"etsc(fun(E) ->
Q = qlc:q([X || {X} <- ets:table(E), element(1,{X}) =:= 1]),
diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl
index 09ce21a428..108ab3bffd 100644
--- a/lib/syntax_tools/src/erl_comment_scan.erl
+++ b/lib/syntax_tools/src/erl_comment_scan.erl
@@ -26,6 +26,7 @@
-export([file/1, join_lines/1, scan_lines/1, string/1]).
+-export_type([comment/0]).
%% =====================================================================
@@ -273,12 +274,8 @@ join_lines([], Txt, L, Col, Ind) ->
filename([C|T]) when is_integer(C), C > 0, C =< 255 ->
[C | filename(T)];
-filename([H|T]) ->
- filename(H) ++ filename(T);
filename([]) ->
[];
-filename(N) when is_atom(N) ->
- atom_to_list(N);
filename(N) ->
report_error("bad filename: `~P'.", [N, 25]),
exit(error).
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index 606441bcf1..c2c72d1ed2 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -384,7 +384,7 @@ lay_postcomments(Cs, D) ->
beside(D, floating(break(stack_comments(Cs, true)), 1, 0)).
%% Format (including padding, if `Pad' is `true', otherwise not)
-%% and stack the listed comments above each other,
+%% and stack the listed comments above each other.
stack_comments([C | Cs], Pad) ->
D = stack_comment_lines(erl_syntax:comment_text(C)),
@@ -405,9 +405,7 @@ stack_comments([C | Cs], Pad) ->
D1; % done
_ ->
above(D1, stack_comments(Cs, Pad))
- end;
-stack_comments([], _) ->
- empty().
+ end.
%% Stack lines of text above each other and prefix each string in
%% the list with a single `%' character.
diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl
index 145bbc6f37..94e760dad7 100644
--- a/lib/syntax_tools/src/erl_recomment.erl
+++ b/lib/syntax_tools/src/erl_recomment.erl
@@ -486,7 +486,7 @@ build_tree(Node) ->
%% Include L, while preserving Min =< Max.
tree_node(minpos(L, Min),
- max(L, Max),
+ erlang:max(L, Max),
erl_syntax:type(Node),
erl_syntax:get_attrs(Node),
Subtrees)
@@ -507,7 +507,7 @@ build_list(Ts) ->
build_list([T | Ts], Min, Max, Ack) ->
Node = build_tree(T),
Min1 = minpos(node_min(Node), Min),
- Max1 = max(node_max(Node), Max),
+ Max1 = erlang:max(node_max(Node), Max),
build_list(Ts, Min1, Max1, [Node | Ack]);
build_list([], Min, Max, Ack) ->
list_node(Min, Max, lists:reverse(Ack)).
@@ -518,7 +518,7 @@ build_list_list(Ls) ->
build_list_list([L | Ls], Min, Max, Ack) ->
Node = build_list(L),
Min1 = minpos(node_min(Node), Min),
- Max1 = max(node_max(Node), Max),
+ Max1 = erlang:max(node_max(Node), Max),
build_list_list(Ls, Min1, Max1, [Node | Ack]);
build_list_list([], Min, Max, Ack) ->
{lists:reverse(Ack), Min, Max}.
@@ -723,9 +723,6 @@ tree_node_attrs(#tree{attrs = Attrs}) ->
%% Just the generic "maximum" function
-max(X, Y) when X > Y -> X;
-max(_, Y) -> Y.
-
%% Return the least positive integer of X and Y, or zero if none of them
%% are positive. (This is necessary for computing minimum source line
%% numbers, since zero (or negative) numbers may occur, but they
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index 9a2967d550..a40bf83c5a 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -309,6 +309,7 @@
data/1,
is_tree/1]).
+-export_type([forms/0, syntaxTree/0, syntaxTreeAttributes/0]).
%% =====================================================================
%% IMPLEMENTATION NOTES:
diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl
index 5c4e074488..4808971a59 100644
--- a/lib/syntax_tools/src/erl_syntax_lib.erl
+++ b/lib/syntax_tools/src/erl_syntax_lib.erl
@@ -46,6 +46,8 @@
new_variable_names/2, new_variable_names/3, strip_comments/1,
to_comment/1, to_comment/2, to_comment/3, variables/1]).
+-export_type([info_pair/0]).
+
%% =====================================================================
-type ordset(X) :: [X]. % XXX: TAKE ME OUT
@@ -400,10 +402,7 @@ new_variable_name(N, R, _T, F, S) ->
%% implementation of `sets'.
start_range(S) ->
- max(sets:size(S) * ?START_RANGE_FACTOR, ?MINIMUM_RANGE).
-
-max(X, Y) when X > Y -> X;
-max(_, Y) -> Y.
+ erlang:max(sets:size(S) * ?START_RANGE_FACTOR, ?MINIMUM_RANGE).
%% The previous number might or might not be used to compute the
%% next number to be tried. It is currently not used.
diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl
index e92e9593b6..702b399615 100644
--- a/lib/syntax_tools/src/igor.erl
+++ b/lib/syntax_tools/src/igor.erl
@@ -699,7 +699,7 @@ merge_files(Name, Trees, Files, Opts) ->
options :: [option()]
}).
--spec merge_sources(atom(), erl_syntax:forms(), [option()]) ->
+-spec merge_sources(atom(), [erl_syntax:forms()], [option()]) ->
{erl_syntax:syntaxTree(), [stubDescriptor()]}.
merge_sources(Name, Sources, Opts) ->
@@ -782,12 +782,12 @@ merge_sources_1(Name, Modules, Trees, Opts) ->
%% however not "safe" by default. If no modules are explicitly
%% specified as static, it is assumed that *all* are static.
Static0 = ordsets:from_list(proplists:append_values(static, Opts)),
- case proplists:is_defined(static, Opts) of
- false ->
- Static = All;
- true ->
- Static = ordsets:add_element(Name, Static0)
- end,
+ Static = case proplists:is_defined(static, Opts) of
+ false ->
+ All;
+ true ->
+ ordsets:add_element(Name, Static0)
+ end,
check_module_names(Static, All, "declared 'static'"),
verbose("static modules: ~p.", [Static], Opts),
@@ -806,8 +806,8 @@ merge_sources_1(Name, Modules, Trees, Opts) ->
verbose("safe modules: ~p.", [Safe], Opts),
Preserved = (ordsets:is_element(Name, Sources)
- and ordsets:is_element(Name, Export))
- or proplists:get_bool(no_banner, Opts),
+ andalso ordsets:is_element(Name, Export))
+ orelse proplists:get_bool(no_banner, Opts),
NoHeaders = proplists:get_bool(no_headers, Opts),
Notes = proplists:get_value(notes, Opts, always),
Rs = proplists:append_values(redirect, Opts),
@@ -2924,9 +2924,7 @@ make_attribute({Name, Term}) ->
[erl_syntax:abstract(Term)]).
is_auto_import({F, A}) ->
- erl_internal:bif(F, A);
-is_auto_import(_) ->
- false.
+ erl_internal:bif(F, A).
timestamp() ->
{{Yr, Mth, Dy}, {Hr, Mt, Sc}} = erlang:localtime(),
diff --git a/lib/syntax_tools/src/prettypr.erl b/lib/syntax_tools/src/prettypr.erl
index 1868f63e54..c13fa30998 100644
--- a/lib/syntax_tools/src/prettypr.erl
+++ b/lib/syntax_tools/src/prettypr.erl
@@ -48,6 +48,8 @@
nest/2, par/1, par/2, sep/1, text/1, null_text/1, text_par/1,
text_par/2]).
+-export_type([document/0]).
+
%% ---------------------------------------------------------------------
-type deep_string() :: [char() | deep_string()].
diff --git a/lib/test_server/src/test_server_node.erl b/lib/test_server/src/test_server_node.erl
index 32886b6765..49025b1a3d 100644
--- a/lib/test_server/src/test_server_node.erl
+++ b/lib/test_server/src/test_server_node.erl
@@ -17,6 +17,7 @@
%% %CopyrightEnd%
%%
-module(test_server_node).
+-compile(r12).
%%%
%%% The same compiled code for this module must be possible to load
diff --git a/lib/test_server/vsn.mk b/lib/test_server/vsn.mk
index e3aac682ec..3c6efeffde 100644
--- a/lib/test_server/vsn.mk
+++ b/lib/test_server/vsn.mk
@@ -1,2 +1,2 @@
-TEST_SERVER_VSN = 3.3.6
+TEST_SERVER_VSN = 3.3.7
diff --git a/lib/tools/emacs/Makefile b/lib/tools/emacs/Makefile
index 0028df247c..8533488463 100644
--- a/lib/tools/emacs/Makefile
+++ b/lib/tools/emacs/Makefile
@@ -42,6 +42,7 @@ EMACS_FILES= \
erlang_appwiz \
erlang-start \
erlang-eunit \
+ erlang-flymake \
erlang
README_FILES= README
diff --git a/lib/tools/emacs/README b/lib/tools/emacs/README
index ca068d04c4..cc107dcd41 100644
--- a/lib/tools/emacs/README
+++ b/lib/tools/emacs/README
@@ -42,7 +42,14 @@ Files\erl-<Ver>:
(setq erlang-root-dir "C:/Program Files/erl<Ver>")
(setq exec-path (cons "C:/Program Files/erl<Ver>/bin" exec-path))
(require 'erlang-start)
-
+Miscellaneous addons
+--------------------
+
+In order to check erlang source code on the fly, add the following
+line to your .emacs file (after erlang-start, see above). See
+erlang-flymake.el for more information on how to customize the syntax
+check.
+ (require 'erlang-flymake)
diff --git a/lib/tools/emacs/erlang-eunit.el b/lib/tools/emacs/erlang-eunit.el
index b2598f93e6..970afe2e9f 100644
--- a/lib/tools/emacs/erlang-eunit.el
+++ b/lib/tools/emacs/erlang-eunit.el
@@ -102,6 +102,13 @@ buffer and vice versa"
(substring base-name (match-beginning 1) (match-end 1))
base-name)))
+;;; Return the module name of the file
+;;; /tmp/foo/src/x.erl --> x
+;;; /tmp/foo/test/x_tests.erl --> x_tests
+(defun erlang-eunit-module-name (file-path)
+ (interactive)
+ (file-name-sans-extension (file-name-nondirectory file-path)))
+
;;; Return the directory name which is common to both src and test
;;; /tmp/foo/src/x.erl --> /tmp/foo
;;; /tmp/foo/test/x_tests.erl --> /tmp/foo
@@ -128,25 +135,62 @@ buffer and vice versa"
(concat dir file)
(concat dir "/" file)))
-;;; Run EUnit tests for the current module
-(defun erlang-eunit-run-tests ()
- "Run the EUnit test suite for the current module.
+;;; Determine options for EUnit.
+(defun erlang-eunit-opts ()
+ (if current-prefix-arg ", [verbose]" ""))
-With prefix arg, runs tests with the verbose flag set."
- (interactive)
+;;; Determine current test function
+(defun erlang-eunit-test-name ()
+ (save-excursion
+ (erlang-end-of-function 1)
+ (erlang-beginning-of-function 1)
+ (erlang-name-of-function)))
+
+(defun erlang-eunit-simple-test-p (test-name)
+ (if (erlang-eunit-string-match-p "^\\(.+\\)_test$" test-name) t nil))
+
+(defun erlang-eunit-test-generator-p (test-name)
+ (if (erlang-eunit-string-match-p "^\\(.+\\)_test_$" test-name) t nil))
+
+;;; Run the current EUnit test
+(defun erlang-eunit-run-current-test ()
(let* ((module-name (erlang-add-quotes-if-needed
- (erlang-eunit-source-module-name buffer-file-name)))
- (opts (if current-prefix-arg ", [verbose]" ""))
- (command (format "eunit:test(%s%s)." module-name opts)))
+ (erlang-eunit-module-name buffer-file-name)))
+ (test-name (erlang-eunit-test-name))
+ (command
+ (cond ((erlang-eunit-simple-test-p test-name)
+ (format "eunit:test({%s, %s}%s)."
+ module-name test-name (erlang-eunit-opts)))
+ ((erlang-eunit-test-generator-p test-name)
+ (format "eunit:test({generator, %s, %s}%s)."
+ module-name test-name (erlang-eunit-opts)))
+ (t (format "%% WARNING: '%s' is not a test function" test-name)))))
(erlang-eunit-inferior-erlang-send-command command)))
-;;; Compile source and EUnit test file and finally run EUnit tests for
-;;; the current module
-(defun erlang-eunit-compile-and-run-tests ()
- "Compile the source and test files and run the EUnit test suite.
+;;; Run EUnit tests for the current module
+(defun erlang-eunit-run-module-tests ()
+ (let* ((module-name (erlang-add-quotes-if-needed
+ (erlang-eunit-source-module-name buffer-file-name)))
+ (command (format "eunit:test(%s%s)." module-name (erlang-eunit-opts))))
+ (erlang-eunit-inferior-erlang-send-command command)))
+
+(defun erlang-eunit-compile-and-run-current-test ()
+ "Compile the source and test files and run the current EUnit test.
With prefix arg, compiles for debug and runs tests with the verbose flag set."
(interactive)
+ (erlang-eunit-compile-and-test 'erlang-eunit-run-current-test))
+
+(defun erlang-eunit-compile-and-run-module-tests ()
+ "Compile the source and test files and run all EUnit tests in the module.
+
+With prefix arg, compiles for debug and runs tests with the verbose flag set."
+ (interactive)
+ (erlang-eunit-compile-and-test 'erlang-eunit-run-module-tests))
+
+;;; Compile source and EUnit test file and finally run EUnit tests for
+;;; the current module
+(defun erlang-eunit-compile-and-test (run-tests)
(let ((src-filename (erlang-eunit-src-filename buffer-file-name))
(test-filename (erlang-eunit-test-filename buffer-file-name)))
@@ -166,7 +210,7 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set."
(if (file-readable-p test-filename)
(erlang-eunit-compile-file test-filename)
t)
- (erlang-eunit-run-tests)))))
+ (funcall run-tests)))))
(defun erlang-eunit-compile-file (file-path)
(if (file-readable-p file-path)
@@ -224,22 +268,18 @@ With prefix arg, compiles for debug and runs tests with the verbose flag set."
;;; Key bindings
;;;====================================================================
-(defvar erlang-eunit-toggle-src-and-test-file-other-window-key "\C-c\C-et"
- "*Key to which the `erlang-eunit-toggle-src-and-test-file-other-window'
-function will be bound.")
-(defvar erlang-eunit-compile-and-run-tests-key "\C-c\C-ek"
- "*Key to which the `erlang-eunit-compile-and-run-tests'
-function will be bound.")
+(defconst erlang-eunit-key-bindings
+ '(("\C-c\C-et" erlang-eunit-toggle-src-and-test-file-other-window)
+ ("\C-c\C-ek" erlang-eunit-compile-and-run-module-tests)
+ ("\C-c\C-ej" erlang-eunit-compile-and-run-current-test)))
(defun erlang-eunit-add-key-bindings ()
- (erlang-eunit-ensure-keymap-for-key
- erlang-eunit-toggle-src-and-test-file-other-window-key)
- (local-set-key erlang-eunit-toggle-src-and-test-file-other-window-key
- 'erlang-eunit-toggle-src-and-test-file-other-window)
- (erlang-eunit-ensure-keymap-for-key
- erlang-eunit-compile-and-run-tests-key)
- (local-set-key erlang-eunit-compile-and-run-tests-key
- 'erlang-eunit-compile-and-run-tests))
+ (dolist (binding erlang-eunit-key-bindings)
+ (erlang-eunit-bind-key (car binding) (cadr binding))))
+
+(defun erlang-eunit-bind-key (key function)
+ (erlang-eunit-ensure-keymap-for-key key)
+ (local-set-key key function))
(defun erlang-eunit-ensure-keymap-for-key (key-seq)
(let ((prefix-keys (butlast (append key-seq nil)))
diff --git a/lib/tools/emacs/erlang-flymake.el b/lib/tools/emacs/erlang-flymake.el
new file mode 100644
index 0000000000..bc368e9454
--- /dev/null
+++ b/lib/tools/emacs/erlang-flymake.el
@@ -0,0 +1,102 @@
+;; erlang-flymake.el
+;;
+;; Syntax check erlang source code on the fly (integrates with flymake).
+;;
+;; Start using flymake with erlang by putting the following somewhere
+;; in your .emacs file:
+;;
+;; (require 'erlang-flymake)
+;;
+;; Flymake is rather eager and does its syntax checks frequently by
+;; default and if you are bothered by this, you might want to put the
+;; following in your .emacs as well:
+;;
+;; (erlang-flymake-only-on-save)
+;;
+;; There are a couple of variables which control the compilation options:
+;; * erlang-flymake-get-code-path-dirs-function
+;; * erlang-flymake-get-include-dirs-function
+;; * erlang-flymake-extra-opts
+;;
+;; This code is inspired by http://www.emacswiki.org/emacs/FlymakeErlang.
+
+(require 'flymake)
+(eval-when-compile
+ (require 'cl))
+
+(defvar erlang-flymake-command
+ "erlc"
+ "The command that will be used to perform the syntax check")
+
+(defvar erlang-flymake-get-code-path-dirs-function
+ 'erlang-flymake-get-code-path-dirs
+ "Return a list of ebin directories to add to the code path.")
+
+(defvar erlang-flymake-get-include-dirs-function
+ 'erlang-flymake-get-include-dirs
+ "Return a list of include directories to add to the compiler options.")
+
+(defvar erlang-flymake-extra-opts
+ (list "+warn_obsolete_guard"
+ "+warn_unused_import"
+ "+warn_shadow_vars"
+ "+warn_export_vars"
+ "+strong_validation"
+ "+report")
+ "A list of options that will be passed to the compiler")
+
+(defun erlang-flymake-only-on-save ()
+ "Trigger flymake only when the buffer is saved (disables syntax
+check on newline and when there are no changes)."
+ (interactive)
+ ;; There doesn't seem to be a way of disabling this; set to the
+ ;; largest int available as a workaround (most-positive-fixnum
+ ;; equates to 8.5 years on my machine, so it ought to be enough ;-) )
+ (setq flymake-no-changes-timeout most-positive-fixnum)
+ (setq flymake-start-syntax-check-on-newline nil))
+
+
+(defun erlang-flymake-get-code-path-dirs ()
+ (list (concat (erlang-flymake-get-app-dir) "ebin")))
+
+(defun erlang-flymake-get-include-dirs ()
+ (list (concat (erlang-flymake-get-app-dir) "include")))
+
+(defun erlang-flymake-get-app-dir ()
+ (let ((src-path (file-name-directory (buffer-file-name))))
+ (file-name-directory (directory-file-name src-path))))
+
+(defun erlang-flymake-init ()
+ (let* ((temp-file
+ (flet ((flymake-get-temp-dir () (erlang-flymake-temp-dir)))
+ (flymake-init-create-temp-buffer-copy
+ 'flymake-create-temp-with-folder-structure)))
+ (code-dir-opts
+ (erlang-flymake-flatten
+ (mapcar (lambda (dir) (list "-pa" dir))
+ (funcall erlang-flymake-get-code-path-dirs-function))))
+ (inc-dir-opts
+ (erlang-flymake-flatten
+ (mapcar (lambda (dir) (list "-I" dir))
+ (funcall erlang-flymake-get-include-dirs-function))))
+ (compile-opts
+ (append inc-dir-opts
+ code-dir-opts
+ erlang-flymake-extra-opts)))
+ (list erlang-flymake-command (append compile-opts (list temp-file)))))
+
+(defun erlang-flymake-temp-dir ()
+ ;; Squeeze the user's name in there in order to make sure that files
+ ;; for two users who are working on the same computer (like a linux
+ ;; box) don't collide
+ (format "%s/flymake-%s" temporary-file-directory user-login-name))
+
+(defun erlang-flymake-flatten (list)
+ (apply #'append list))
+
+(add-to-list 'flymake-allowed-file-name-masks
+ '("\\.erl\\'" erlang-flymake-init))
+(add-hook 'erlang-mode-hook 'flymake-mode)
+
+(provide 'erlang-flymake)
+;; erlang-flymake ends here
diff --git a/lib/tools/emacs/erlang-start.el b/lib/tools/emacs/erlang-start.el
index 542e81f24c..bbcea3e46a 100644
--- a/lib/tools/emacs/erlang-start.el
+++ b/lib/tools/emacs/erlang-start.el
@@ -90,6 +90,11 @@
(or (assoc (car b) auto-mode-alist)
(setq auto-mode-alist (cons b auto-mode-alist))))
+;;
+;; Associate files using interpreter "escript" with Erlang mode.
+;;
+
+(add-to-list 'interpreter-mode-alist (cons "escript" 'erlang-mode))
;;
;; Ignore files ending in ".jam", ".vee", and ".beam" when performing
diff --git a/lib/tools/emacs/erlang.el b/lib/tools/emacs/erlang.el
index a84f40244d..91acfdf2b6 100644
--- a/lib/tools/emacs/erlang.el
+++ b/lib/tools/emacs/erlang.el
@@ -659,24 +659,30 @@ resulting regexp is surrounded by \\_< and \\_>."
(eval-and-compile
(defconst erlang-guards-regexp (erlang-regexp-opt erlang-guards 'symbols)))
-
(eval-and-compile
(defvar erlang-predefined-types
'("any"
"arity"
+ "boolean"
"byte"
"char"
"cons"
"deep_string"
+ "iolist"
"maybe_improper_list"
+ "module"
"mfa"
"nil"
+ "neg_integer"
"none"
"non_neg_integer"
"nonempty_list"
"nonempty_improper_list"
"nonempty_maybe_improper_list"
+ "no_return"
+ "pos_integer"
"string"
+ "term"
"timeout")
"Erlang type specs types"))
@@ -885,15 +891,54 @@ files written in other languages than Erlang.")
If nil, the inferior shell replaces the window. This is the traditional
behaviour.")
-(defvar erlang-mode-map nil
+(defconst inferior-erlang-use-cmm (boundp 'minor-mode-overriding-map-alist)
+ "Non-nil means use `compilation-minor-mode' in Erlang shell.")
+
+(defvar erlang-mode-map
+ (let ((map (make-sparse-keymap)))
+ (unless (boundp 'indent-line-function)
+ (define-key map "\t" 'erlang-indent-command))
+ (define-key map ";" 'erlang-electric-semicolon)
+ (define-key map "," 'erlang-electric-comma)
+ (define-key map "<" 'erlang-electric-lt)
+ (define-key map ">" 'erlang-electric-gt)
+ (define-key map "\C-m" 'erlang-electric-newline)
+ (if (not (boundp 'delete-key-deletes-forward))
+ (define-key map "\177" 'backward-delete-char-untabify)
+ (define-key map [(backspace)] 'backward-delete-char-untabify))
+ ;;(unless (boundp 'fill-paragraph-function)
+ (define-key map "\M-q" 'erlang-fill-paragraph)
+ (unless (boundp 'beginning-of-defun-function)
+ (define-key map "\M-\C-a" 'erlang-beginning-of-function)
+ (define-key map "\M-\C-e" 'erlang-end-of-function)
+ (define-key map '(meta control h) 'erlang-mark-function)) ; Xemacs
+ (define-key map "\M-\t" 'erlang-complete-tag)
+ (define-key map "\C-c\M-\t" 'tempo-complete-tag)
+ (define-key map "\M-+" 'erlang-find-next-tag)
+ (define-key map "\C-c\M-a" 'erlang-beginning-of-clause)
+ (define-key map "\C-c\M-b" 'tempo-backward-mark)
+ (define-key map "\C-c\M-e" 'erlang-end-of-clause)
+ (define-key map "\C-c\M-f" 'tempo-forward-mark)
+ (define-key map "\C-c\M-h" 'erlang-mark-clause)
+ (define-key map "\C-c\C-c" 'comment-region)
+ (define-key map "\C-c\C-j" 'erlang-generate-new-clause)
+ (define-key map "\C-c\C-k" 'erlang-compile)
+ (define-key map "\C-c\C-l" 'erlang-compile-display)
+ (define-key map "\C-c\C-s" 'erlang-show-syntactic-information)
+ (define-key map "\C-c\C-q" 'erlang-indent-function)
+ (define-key map "\C-c\C-u" 'erlang-uncomment-region)
+ (define-key map "\C-c\C-y" 'erlang-clone-arguments)
+ (define-key map "\C-c\C-a" 'erlang-align-arrows)
+ (define-key map "\C-c\C-z" 'erlang-shell-display)
+ (unless inferior-erlang-use-cmm
+ (define-key map "\C-x`" 'erlang-next-error))
+ map)
"*Keymap used in Erlang mode.")
(defvar erlang-mode-abbrev-table nil
"Abbrev table in use in Erlang-mode buffers.")
(defvar erlang-mode-syntax-table nil
"Syntax table in use in Erlang-mode buffers.")
-(defconst inferior-erlang-use-cmm (boundp 'minor-mode-overriding-map-alist)
- "Non-nil means use `compilation-minor-mode' in Erlang shell.")
(defvar erlang-skel-file "erlang-skels"
@@ -988,7 +1033,7 @@ behaviour.")
(list (concat "^\\(-" erlang-atom-regexp "\\)\\(\\s-\\|\\.\\|(\\)")
1 (if (boundp 'font-lock-preprocessor-face)
'font-lock-preprocessor-face
- 'font-lock-function-name-face)))
+ 'font-lock-constant-face)))
"Font lock keyword highlighting attributes.")
(defvar erlang-font-lock-keywords-quotes
@@ -1019,10 +1064,12 @@ are highlighted by syntactic analysis.")
(list
(list (concat "?\\s-*\\(" erlang-atom-regexp
"\\|" erlang-variable-regexp "\\)")
- 1 'font-lock-type-face)
+ 1 'font-lock-constant-face)
(list (concat "^\\(-\\(?:define\\|ifn?def\\)\\)\\s-*(\\s-*\\(" erlang-atom-regexp
"\\|" erlang-variable-regexp "\\)")
- (list 1 'font-lock-preprocessor-face t)
+ (if (boundp 'font-lock-preprocessor-face)
+ (list 1 'font-lock-preprocessor-face t)
+ (list 1 'font-lock-constant-face t))
(list 3 'font-lock-type-face t t))
(list "^-e\\(lse\\|ndif\\)\\>" 0 'font-lock-preprocessor-face t))
"Font lock keyword highlighting macros.
@@ -1245,7 +1292,7 @@ Other commands:
(setq major-mode 'erlang-mode)
(setq mode-name "Erlang")
(erlang-syntax-table-init)
- (erlang-keymap-init)
+ (use-local-map erlang-mode-map)
(erlang-electric-init)
(erlang-menu-init)
(erlang-mode-variables)
@@ -1300,53 +1347,6 @@ Other commands:
(set-syntax-table erlang-mode-syntax-table))
-(defun erlang-keymap-init ()
- (if erlang-mode-map
- nil
- (setq erlang-mode-map (make-sparse-keymap))
- (erlang-mode-commands erlang-mode-map))
- (use-local-map erlang-mode-map))
-
-
-(defun erlang-mode-commands (map)
- (unless (boundp 'indent-line-function)
- (define-key map "\t" 'erlang-indent-command))
- (define-key map ";" 'erlang-electric-semicolon)
- (define-key map "," 'erlang-electric-comma)
- (define-key map "<" 'erlang-electric-lt)
- (define-key map ">" 'erlang-electric-gt)
- (define-key map "\C-m" 'erlang-electric-newline)
- (if (not (boundp 'delete-key-deletes-forward))
- (define-key map "\177" 'backward-delete-char-untabify)
- (define-key map [(backspace)] 'backward-delete-char-untabify))
- ;;(unless (boundp 'fill-paragraph-function)
- (define-key map "\M-q" 'erlang-fill-paragraph)
- (unless (boundp 'beginning-of-defun-function)
- (define-key map "\M-\C-a" 'erlang-beginning-of-function)
- (define-key map "\M-\C-e" 'erlang-end-of-function)
- (define-key map '(meta control h) 'erlang-mark-function)) ; Xemacs
- (define-key map "\M-\t" 'erlang-complete-tag)
- (define-key map "\C-c\M-\t" 'tempo-complete-tag)
- (define-key map "\M-+" 'erlang-find-next-tag)
- (define-key map "\C-c\M-a" 'erlang-beginning-of-clause)
- (define-key map "\C-c\M-b" 'tempo-backward-mark)
- (define-key map "\C-c\M-e" 'erlang-end-of-clause)
- (define-key map "\C-c\M-f" 'tempo-forward-mark)
- (define-key map "\C-c\M-h" 'erlang-mark-clause)
- (define-key map "\C-c\C-c" 'comment-region)
- (define-key map "\C-c\C-j" 'erlang-generate-new-clause)
- (define-key map "\C-c\C-k" 'erlang-compile)
- (define-key map "\C-c\C-l" 'erlang-compile-display)
- (define-key map "\C-c\C-s" 'erlang-show-syntactic-information)
- (define-key map "\C-c\C-q" 'erlang-indent-function)
- (define-key map "\C-c\C-u" 'erlang-uncomment-region)
- (define-key map "\C-c\C-y" 'erlang-clone-arguments)
- (define-key map "\C-c\C-a" 'erlang-align-arrows)
- (define-key map "\C-c\C-z" 'erlang-shell-display)
- (unless inferior-erlang-use-cmm
- (define-key map "\C-x`" 'erlang-next-error)))
-
-
(defun erlang-electric-init ()
;; Set up electric character functions to work with
;; delsel/pending-del mode. Also, set up text properties for bit
@@ -1400,7 +1400,7 @@ Other commands:
(set (make-local-variable 'imenu-prev-index-position-function)
'erlang-beginning-of-function)
(set (make-local-variable 'imenu-extract-index-name-function)
- 'erlang-get-function-name)
+ 'erlang-get-function-name-and-arity)
(set (make-local-variable 'tempo-match-finder)
"[^-a-zA-Z0-9_]\\([-a-zA-Z0-9_]*\\)\\=")
(set (make-local-variable 'beginning-of-defun-function)
@@ -2490,9 +2490,10 @@ Value is list (stack token-start token-type in-what)."
((looking-at "\\(of\\)[^_a-zA-Z0-9]")
;; Must handle separately, try X of -> catch
(if (and stack (eq (car (car stack)) 'try))
- (let ((try-column (nth 2 (car stack))))
+ (let ((try-column (nth 2 (car stack)))
+ (try-pos (nth 1 (car stack))))
(erlang-pop stack)
- (erlang-push (list 'icr token try-column) stack))))
+ (erlang-push (list 'icr try-pos try-column) stack))))
((looking-at "\\(fun\\)[^_a-zA-Z0-9]")
;; Push a new layer if we are defining a `fun'
@@ -2753,7 +2754,7 @@ Return nil if inside string, t if in a comment."
;;
;; `after' should be indented to the same level as the
;; corresponding receive.
- (cond ((looking-at "\\(after\\|catch\\|of\\)\\($\\|[^_a-zA-Z0-9]\\)")
+ (cond ((looking-at "\\(after\\|of\\)\\($\\|[^_a-zA-Z0-9]\\)")
(nth 2 stack-top))
((looking-at "when[^_a-zA-Z0-9]")
;; Handling one when part
@@ -2772,7 +2773,7 @@ Return nil if inside string, t if in a comment."
((and (eq (car stack-top) '||) (looking-at "\\(]\\|>>\\)[^_a-zA-Z0-9]"))
(nth 2 (car (cdr stack))))
;; Real indentation, where operators create extra indentation etc.
- ((memq (car stack-top) '(-> || begin try))
+ ((memq (car stack-top) '(-> || try begin))
(if (looking-at "\\(of\\)[^_a-zA-Z0-9]")
(nth 2 stack-top)
(goto-char (nth 1 stack-top))
@@ -2801,19 +2802,24 @@ Return nil if inside string, t if in a comment."
(erlang-caddr (car stack))
0))
((looking-at "catch\\($\\|[^_a-zA-Z0-9]\\)")
- (if (or (eq (car stack-top) 'try)
- (eq (car (car (cdr stack))) 'icr))
- (progn
- (if (eq (car stack-top) '->)
- (erlang-pop stack))
- (if stack
- (erlang-caddr (car stack))
- 0))
- base)) ;; old catch
+ ;; Are we in a try
+ (let ((start (if (eq (car stack-top) '->)
+ (car (cdr stack))
+ stack-top)))
+ (if (null start) nil
+ (goto-char (nth 1 start)))
+ (cond ((looking-at "try\\($\\|[^_a-zA-Z0-9]\\)")
+ (progn
+ (if (eq (car stack-top) '->)
+ (erlang-pop stack))
+ (if stack
+ (erlang-caddr (car stack))
+ 0)))
+ (t (erlang-indent-standard indent-point token base 'nil))))) ;; old catch
(t
(erlang-indent-standard indent-point token base 'nil)
))))
- ))
+ ))
((eq (car stack-top) 'when)
(goto-char (nth 1 stack-top))
(if (looking-at "when\\s *\\($\\|%\\)")
@@ -2839,27 +2845,32 @@ Return nil if inside string, t if in a comment."
(current-column)))
;; Type and Spec indentation
((eq (car stack-top) '::)
- (cond ((null erlang-argument-indent)
- ;; indent to next column.
- (+ 2 (nth 2 stack-top)))
- ((looking-at "::[^_a-zA-Z0-9]")
- (nth 2 stack-top))
- (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)
+ (if (looking-at "}")
+ ;; Closing record definition with types
+ ;; pop stack and recurse
+ (erlang-calculate-stack-indent indent-point
+ (cons (erlang-pop stack) (cdr state)))
+ (cond ((null erlang-argument-indent)
+ ;; indent to next column.
+ (+ 2 (nth 2 stack-top)))
+ ((looking-at "::[^_a-zA-Z0-9]")
+ (nth 2 stack-top))
+ (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)))))
+ (+ (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)
@@ -2931,10 +2942,16 @@ This assumes that the preceding expression is either simple
(skip-chars-backward " \t")
;; Needed to match the colon in "'foo':'bar'".
(if (not (memq (preceding-char) '(?# ?:)))
- col
- (backward-char 1)
- (forward-sexp -1)
- (current-column)))))
+ col
+ ;; Special hack to handle: (note line break)
+ ;; [#myrecord{
+ ;; foo = foo}]
+ (or
+ (ignore-errors
+ (backward-char 1)
+ (forward-sexp -1)
+ (current-column))
+ col)))))
(defun erlang-indent-parenthesis (stack-position)
(let ((previous (erlang-indent-find-preceding-expr)))
@@ -3503,6 +3520,13 @@ Normally used in conjunction with `erlang-beginning-of-clause', e.g.:
res)
(error nil)))))
+(defun erlang-get-function-name-and-arity ()
+ "Return the name and arity of the function at point, or nil.
+The return value is a string of the form \"foo/1\"."
+ (let ((name (erlang-get-function-name))
+ (arity (erlang-get-function-arity)))
+ (and name arity (format "%s/%d" name arity))))
+
(defun erlang-get-function-arguments ()
"Return arguments of current function, or nil."
(if (not (looking-at (eval-when-compile
@@ -4899,9 +4923,14 @@ a prompt. When nil, we will wait forever, or until \\[keyboard-quit].")
(defvar inferior-erlang-buffer nil
"Buffer of last invoked inferior Erlang, or nil.")
+;; Enable uniquifying Erlang shell buffers based on directory name.
+(eval-after-load "uniquify"
+ '(add-to-list 'uniquify-list-buffers-directory-modes 'erlang-shell-mode))
+
;;;###autoload
-(defun inferior-erlang ()
+(defun inferior-erlang (&optional command)
"Run an inferior Erlang.
+With prefix command, prompt for command to start Erlang with.
This is just like running Erlang in a normal shell, except that
an Emacs buffer is used for input and output.
@@ -4915,17 +4944,37 @@ Entry to this mode calls the functions in the variables
The following commands imitate the usual Unix interrupt and
editing control characters:
\\{erlang-shell-mode-map}"
- (interactive)
+ (interactive
+ (when current-prefix-arg
+ (list (if (fboundp 'read-shell-command)
+ ;; `read-shell-command' is a new function in Emacs 23.
+ (read-shell-command "Erlang command: ")
+ (read-string "Erlang command: ")))))
(require 'comint)
- (let ((opts inferior-erlang-machine-options))
- (cond ((eq inferior-erlang-shell-type 'oldshell)
- (setq opts (cons "-oldshell" opts)))
- ((eq inferior-erlang-shell-type 'newshell)
- (setq opts (append '("-newshell" "-env" "TERM" "vt100") opts))))
- (setq inferior-erlang-buffer
- (apply 'make-comint
- inferior-erlang-process-name inferior-erlang-machine
- nil opts)))
+ (let (cmd opts)
+ (if command
+ (setq cmd "sh"
+ opts (list "-c" command))
+ (setq cmd inferior-erlang-machine
+ opts inferior-erlang-machine-options)
+ (cond ((eq inferior-erlang-shell-type 'oldshell)
+ (setq opts (cons "-oldshell" opts)))
+ ((eq inferior-erlang-shell-type 'newshell)
+ (setq opts (append '("-newshell" "-env" "TERM" "vt100") opts)))))
+
+ ;; Using create-file-buffer and list-buffers-directory in this way
+ ;; makes uniquify give each buffer a unique name based on the
+ ;; directory.
+ (let ((fake-file-name (expand-file-name inferior-erlang-buffer-name default-directory)))
+ (setq inferior-erlang-buffer (create-file-buffer fake-file-name))
+ (apply 'make-comint-in-buffer
+ inferior-erlang-process-name
+ inferior-erlang-buffer
+ cmd
+ nil opts)
+ (with-current-buffer inferior-erlang-buffer
+ (setq list-buffers-directory fake-file-name))))
+
(setq inferior-erlang-process
(get-buffer-process inferior-erlang-buffer))
(if (> 21 erlang-emacs-major-version) ; funcalls to avoid compiler warnings
@@ -4938,10 +4987,6 @@ editing control characters:
(if (and (not (eq system-type 'windows-nt))
(eq inferior-erlang-shell-type 'newshell))
(setq comint-process-echoes t))
- ;; `rename-buffer' takes only one argument in Emacs 18.
- (condition-case nil
- (rename-buffer inferior-erlang-buffer-name t)
- (error (rename-buffer inferior-erlang-buffer-name)))
(erlang-shell-mode))
diff --git a/lib/tools/emacs/test.erl.indented b/lib/tools/emacs/test.erl.indented
index d0ea4c29cf..2948ccf1b5 100644
--- a/lib/tools/emacs/test.erl.indented
+++ b/lib/tools/emacs/test.erl.indented
@@ -93,11 +93,27 @@
-type t13() :: maybe_improper_list(integer(), t11()).
-type t14() :: [erl_scan:foo() |
%% Should be highlighted
- non_neg_integer() | nonempty_list() |
+ term() |
+ bool() |
+ byte() |
+ char() |
+ non_neg_integer() | nonempty_list() |
+ pos_integer() |
+ neg_integer() |
+ number() |
+ list() |
nonempty_improper_list() | nonempty_maybe_improper_list() |
+ maybe_improper_list() | string() | iolist() | byte() |
+ module() |
+ mfa() |
+ node() |
+ timeout() |
+ no_return() |
%% Should not be highlighted
nonempty_() | nonlist() |
- erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
+ erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
+
+
-type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>,
<<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>|
<<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
@@ -172,6 +188,9 @@
f19 = 3 :: integer()|undefined,
f5 = 3 :: undefined|integer()}).
+-record(state, {
+ sequence_number = 1 :: integer()
+ }).
highlighting(X) % Function definitions should be highlighted
@@ -493,7 +512,9 @@ indent_try_catch() ->
file:close(Xfile)
end;
indent_try_catch() ->
- try foo(bar) of
+ try
+ foo(bar)
+ of
X when true andalso
kalle ->
io:format(stdout, "Parsing file ~s, ",
@@ -551,14 +572,57 @@ indent_catch() ->
C = catch B +
float(43.1),
- case catch (X) of
+ case catch foo(X) of
+ A ->
+ B
+ end,
+
+ case
+ catch foo(X)
+ of
A ->
B
end,
+
+ case
+ foo(X)
+ of
+ A ->
+ catch B,
+ X
+ end,
+
try sune of
_ -> foo
catch _:_ -> baf
- end.
+ end,
+
+ try
+ sune
+ of
+ _ ->
+ X = 5,
+ (catch foo(X)),
+ X + 10
+ catch _:_ -> baf
+ end,
+
+ try
+ (catch sune)
+ of
+ _ ->
+ catch foo() %% BUGBUG can't handle catch inside try without parentheses
+ catch _:_ ->
+ baf
+ end,
+
+ try
+ (catch exit())
+ catch
+ _ ->
+ catch baf()
+ end,
+ ok.
indent_binary() ->
X = lists:foldr(fun(M) ->
@@ -588,3 +652,8 @@ indent_comprehensions() ->
true = (X rem 2)
>>,
ok.
+
+%% This causes an error in earlier erlang-mode versions.
+foo() ->
+ [#foo{
+ foo = foo}].
diff --git a/lib/tools/emacs/test.erl.orig b/lib/tools/emacs/test.erl.orig
index 70e97a2e91..1221c5655e 100644
--- a/lib/tools/emacs/test.erl.orig
+++ b/lib/tools/emacs/test.erl.orig
@@ -93,11 +93,27 @@
-type t13() :: maybe_improper_list(integer(), t11()).
-type t14() :: [erl_scan:foo() |
%% Should be highlighted
- non_neg_integer() | nonempty_list() |
+ term() |
+ bool() |
+ byte() |
+ char() |
+ non_neg_integer() | nonempty_list() |
+ pos_integer() |
+ neg_integer() |
+ number() |
+ list() |
nonempty_improper_list() | nonempty_maybe_improper_list() |
+ maybe_improper_list() | string() | iolist() | byte() |
+ module() |
+ mfa() |
+ node() |
+ timeout() |
+ no_return() |
%% Should not be highlighted
nonempty_() | nonlist() |
-erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
+ erl_scan:bar(34, 92) | t13() | m:f(integer() | <<_:_*16>>)].
+
+
-type t15() :: {binary(),<<>>,<<_:34>>,<<_:_*42>>,
<<_:3,_:_*14>>,<<>>} | [<<>>|<<_:34>>|<<_:16>>|
<<_:3,_:_*1472>>|<<_:19,_:_*14>>| <<_:34>>|
@@ -172,6 +188,9 @@ f18 :: 1 | 2 | 'undefined',
f19 = 3 :: integer()|undefined,
f5 = 3 :: undefined|integer()}).
+-record(state, {
+ sequence_number = 1 :: integer()
+ }).
highlighting(X) % Function definitions should be highlighted
@@ -493,7 +512,9 @@ indent_try_catch() ->
file:close(Xfile)
end;
indent_try_catch() ->
- try foo(bar) of
+ try
+ foo(bar)
+ of
X when true andalso
kalle ->
io:format(stdout, "Parsing file ~s, ",
@@ -551,14 +572,57 @@ indent_catch() ->
C = catch B +
float(43.1),
- case catch (X) of
+ case catch foo(X) of
A ->
B
end,
+
+ case
+ catch foo(X)
+ of
+ A ->
+ B
+ end,
+
+ case
+ foo(X)
+ of
+ A ->
+ catch B,
+ X
+ end,
+
try sune of
- _ -> foo
- catch _:_ -> baf
- end.
+ _ -> foo
+ catch _:_ -> baf
+ end,
+
+ try
+sune
+ of
+ _ ->
+ X = 5,
+ (catch foo(X)),
+ X + 10
+ catch _:_ -> baf
+ end,
+
+ try
+ (catch sune)
+ of
+ _ ->
+ catch foo() %% BUGBUG can't handle catch inside try without parentheses
+ catch _:_ ->
+ baf
+ end,
+
+ try
+(catch exit())
+ catch
+_ ->
+ catch baf()
+ end,
+ ok.
indent_binary() ->
X = lists:foldr(fun(M) ->
@@ -588,3 +652,8 @@ Binary2 = << <<X:8>> || <<X:32,_:32>> <= <<0:512>>,
true = (X rem 2)
>>,
ok.
+
+%% This causes an error in earlier erlang-mode versions.
+foo() ->
+[#foo{
+foo = foo}].
diff --git a/lib/tools/src/xref_base.erl b/lib/tools/src/xref_base.erl
index d0dbf4a2b4..1656899e8f 100644
--- a/lib/tools/src/xref_base.erl
+++ b/lib/tools/src/xref_base.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%
%%
@@ -29,7 +29,7 @@
add_release/2, add_release/3,
get_library_path/1, set_library_path/2, set_library_path/3,
set_up/1, set_up/2,
- q/2, q/3, info/1, info/2, info/3, update/1, update/2,
+ q/2, q/3, info/1, info/2, info/3, update/1, update/2,
forget/1, forget/2, variables/1, variables/2,
analyze/2, analyze/3, analysis/1,
get_default/2, set_default/3,
@@ -38,14 +38,14 @@
-export([format_error/1]).
%% The following functions are exported for testing purposes only:
--export([do_add_module/4, do_add_application/2, do_add_release/2,
+-export([do_add_module/4, do_add_application/2, do_add_release/2,
do_remove_module/2]).
--import(lists,
- [filter/2, flatten/1, foldl/3, keysearch/3, map/2, mapfoldl/3,
- member/2, reverse/1, sort/1, usort/1]).
+-import(lists,
+ [filter/2, flatten/1, foldl/3, foreach/2, keysearch/3, map/2,
+ mapfoldl/3, member/2, reverse/1, sort/1, usort/1]).
--import(sofs,
+-import(sofs,
[constant_function/2, converse/1, difference/2, domain/1,
empty_set/0, family/1, family_difference/2, intersection/2,
family_projection/2, family_to_relation/1, family_union/1,
@@ -103,12 +103,12 @@ delete(State) ->
ok
end
end,
- map(Fun, dict:to_list(State#xref.variables)),
+ foreach(Fun, dict:to_list(State#xref.variables)),
ok.
add_directory(State, Dir) ->
add_directory(State, Dir, []).
-
+
%% -> {ok, Modules, NewState} | Error
add_directory(State, Dir, Options) ->
ValOptions = option_values([builtins, recurse, verbose, warnings], State),
@@ -277,7 +277,7 @@ q(S, Q, Options) when is_atom(Q) ->
q(S, atom_to_list(Q), Options);
q(S, Q, Options) ->
case xref_utils:is_string(Q, 1) of
- true ->
+ true ->
case set_up(S, Options) of
{ok, S1} ->
case xref_compiler:compile(Q, S1#xref.variables) of
@@ -336,7 +336,7 @@ forget(State, Variable) when is_atom(Variable) ->
forget(State, Variables) ->
Vars = State#xref.variables,
do_forget(Variables, Vars, Variables, State).
-
+
variables(State) ->
variables(State, [user]).
@@ -350,9 +350,9 @@ variables(State, Options) ->
{ok, NewState} ->
{U, P} = do_variables(NewState),
R1 = if User -> [{user, U}]; true -> [] end,
- R = if
- Predef -> [{predefined,P} | R1];
- true -> R1
+ R = if
+ Predef -> [{predefined,P} | R1];
+ true -> R1
end,
{{ok, R}, NewState};
Error ->
@@ -368,7 +368,7 @@ analyze(State, Analysis) ->
%% -> {{ok, Answer}, NewState} | {Error, NewState}
analyze(State, Analysis, Options) ->
case analysis(Analysis, State#xref.mode) of
- P when is_list(P) ->
+ P when is_list(P) ->
q(State, P, Options);
error ->
R = case analysis(Analysis, functions) of
@@ -461,7 +461,7 @@ get_default(State, Option) ->
%% -> [{Option, Value}]
get_default(State) ->
- Fun = fun(O) -> V = current_default(State, O), {O, V} end,
+ Fun = fun(O) -> V = current_default(State, O), {O, V} end,
map(Fun, [builtins, recurse, verbose, warnings]).
%% -> {ok, NewState} -> Error
@@ -478,7 +478,7 @@ set_default(State, Options) ->
format_error({error, Module, Error}) ->
Module:format_error(Error);
format_error({invalid_options, Options}) ->
- io_lib:format("Unknown option(s) or invalid option value(s): ~p~n",
+ io_lib:format("Unknown option(s) or invalid option value(s): ~p~n",
[Options]);
format_error({invalid_filename, Term}) ->
io_lib:format("A file name (a string) was expected: ~p~n", [Term]);
@@ -540,7 +540,7 @@ updated_modules(State) ->
case xref_utils:file_info(File) of
{ok, {_, file, readable, MTime}} when MTime =/= RTime ->
[{M,File} | L];
- _Else ->
+ _Else ->
L
end
end,
@@ -591,7 +591,7 @@ do_add_release(Dir, RelName, OB, OV, OW, State) ->
case xref_utils:release_directory(Dir, true, "ebin") of
{ok, ReleaseDirName, ApplDir, Dirs} ->
ApplDirs = xref_utils:select_last_application_version(Dirs),
- Release = case RelName of
+ Release = case RelName of
[[]] -> ReleaseDirName;
[Name] -> Name
end,
@@ -615,7 +615,7 @@ do_add_release(S, XRel) ->
end.
add_rel_appls([ApplDir | ApplDirs], Release, OB, OV, OW, State) ->
- {ok, _AppName, NewState} =
+ {ok, _AppName, NewState} =
add_appldir(ApplDir, Release, [[]], OB, OV, OW, State),
add_rel_appls(ApplDirs, Release, OB, OV, OW, NewState);
add_rel_appls([], [Release], _OB, _OV, _OW, NewState) ->
@@ -637,10 +637,10 @@ add_appldir(ApplDir, Release, Name, OB, OV, OW, OldState) ->
[[]] -> AppName0;
[N] -> N
end,
- AppInfo = #xref_app{name = AppName, rel_name = Release,
+ AppInfo = #xref_app{name = AppName, rel_name = Release,
vsn = Vsn, dir = Dir},
State1 = do_add_application(OldState, AppInfo),
- {ok, _Modules, NewState} =
+ {ok, _Modules, NewState} =
do_add_directory(Dir, [AppName], OB, false, OV, OW, State1),
{ok, AppName, NewState}.
@@ -662,7 +662,7 @@ do_add_directory(Dir, AppName, Bui, Rec, Ver, War, State) ->
ok = is_filename(Dir),
{FileNames, Errors, Jams, Unreadable} =
xref_utils:scan_directory(Dir, Rec, [?Suffix], [".jam"]),
- warnings(War, jam, Jams),
+ warnings(War, jam, Jams),
warnings(War, unreadable, Unreadable),
case Errors of
[] ->
@@ -683,7 +683,7 @@ do_add_a_module(File, AppName, Builtins, Verbose, Warnings, State) ->
false ->
throw_error({invalid_filename, File});
Splitname ->
- do_add_module(Splitname, AppName, Builtins, Verbose,
+ do_add_module(Splitname, AppName, Builtins, Verbose,
Warnings, State)
end.
@@ -691,7 +691,7 @@ do_add_a_module(File, AppName, Builtins, Verbose, Warnings, State) ->
%% Options: verbose, warnings, builtins
do_add_module({Dir, Basename}, AppName, Builtins, Verbose, Warnings, State) ->
File = filename:join(Dir, Basename),
- {ok, M, Bad, NewState} =
+ {ok, M, Bad, NewState} =
do_add_module1(Dir, File, AppName, Builtins, Verbose, Warnings, State),
filter(fun({Tag,B}) -> warnings(Warnings, Tag, [[File,B]]) end, Bad),
{ok, M, NewState}.
@@ -723,7 +723,7 @@ do_add_module1(Dir, File, AppName, Builtins, Verbose, Warnings, State) ->
{ok, {_, _, _, Time}} -> Time;
Error -> throw(Error)
end,
- XMod = #xref_mod{name = M, app_name = AppName, dir = Dir,
+ XMod = #xref_mod{name = M, app_name = AppName, dir = Dir,
mtime = T, builtins = Builtins,
no_unresolved = NoUnresCalls},
do_add_module(State, XMod, UnresCalls, Data);
@@ -736,13 +736,13 @@ abst(File, Builtins, Mode) when Mode =:= functions ->
case beam_lib:chunks(File, [abstract_code, exports, attributes]) of
{ok, {M,[{abstract_code,NoA},_X,_A]}} when NoA =:= no_abstract_code ->
{ok, M, NoA};
- {ok, {M, [{abstract_code, {abstract_v1, Forms}},
+ {ok, {M, [{abstract_code, {abstract_v1, Forms}},
{exports,X0}, {attributes,A}]}} ->
%% R7.
X = xref_utils:fa_to_mfa(X0, M),
D = deprecated(A, X, M),
xref_reader:module(M, Forms, Builtins, X, D);
- {ok, {M, [{abstract_code, {abstract_v2, Forms}},
+ {ok, {M, [{abstract_code, {abstract_v2, Forms}},
{exports,X0}, {attributes,A}]}} ->
%% R8-R9B.
X = xref_utils:fa_to_mfa(X0, M),
@@ -769,8 +769,8 @@ abst(File, Builtins, Mode) when Mode =:= modules ->
true ->
I0;
false ->
- Fun = fun({M,F,A}) ->
- not xref_utils:is_builtin(M, F, A)
+ Fun = fun({M,F,A}) ->
+ not xref_utils:is_builtin(M, F, A)
end,
filter(Fun, I0)
end,
@@ -790,7 +790,7 @@ mfa_exports(X0, Attributes, M) ->
xref_utils:fa_to_mfa(X1, M).
adjust_arity(F, A) ->
- case xref_utils:is_static_function(F, A) of
+ case xref_utils:is_static_function(F, A) of
true -> A;
false -> A - 1
end.
@@ -885,7 +885,7 @@ do_add_module(S, M, XMod, Unres0, Data) when S#xref.mode =:= functions ->
Unres = domain(UnresCalls),
DefinedFuns = domain(DefAt),
- {AXC, ALC, Bad1, LPreCAt2, XPreCAt2} =
+ {AXC, ALC, Bad1, LPreCAt2, XPreCAt2} =
extra_edges(AXC1, ALC1, Bad0, DefinedFuns),
Bad = map(fun(B) -> {xref_attr, B} end, Bad1),
LPreCAt = union(LPreCAt1, LPreCAt2),
@@ -904,8 +904,8 @@ do_add_module(S, M, XMod, Unres0, Data) when S#xref.mode =:= functions ->
%% {EE, ECallAt} = inter_graph(X, L, LC, XC, LCallAt, XCallAt),
Self = self(),
- Fun = fun() -> inter_graph(Self, X, L, LC, XC, CallAt) end,
- {EE, ECallAt} =
+ Fun = fun() -> inter_graph(Self, X, L, LC, XC, CallAt) end,
+ {EE, ECallAt} =
xref_utils:subprocess(Fun, [link, {min_heap_size,100000}]),
[DefAt2,L2,X2,LCallAt2,XCallAt2,CallAt2,LC2,XC2,EE2,ECallAt2,
@@ -977,13 +977,13 @@ extra_edges(CAX, CAL, Bad0, F) ->
ALC = restriction(2, restriction(ALC0, F), F),
LPreCAt2 = restriction(CAL, ALC),
XPreCAt2 = restriction(CAX, AXC),
- Bad = Bad0 ++ to_external(difference(AXC0, AXC))
+ Bad = Bad0 ++ to_external(difference(AXC0, AXC))
++ to_external(difference(ALC0, ALC)),
{AXC, ALC, Bad, LPreCAt2, XPreCAt2}.
no_info(X, L, LC, XC, EE, Unres, NoCalls, NoUnresCalls) ->
NoUnres = no_elements(Unres),
- [{no_calls, {NoCalls-NoUnresCalls, NoUnresCalls}},
+ [{no_calls, {NoCalls-NoUnresCalls, NoUnresCalls}},
{no_function_calls, {no_elements(LC), no_elements(XC)-NoUnres, NoUnres}},
{no_functions, {no_elements(L), no_elements(X)}},
%% Note: this is overwritten in do_set_up():
@@ -1011,10 +1011,10 @@ inter_graph(X, L, LC, XC, CallAt) ->
Es = union(LEs, XEs),
E1 = to_external(restriction(difference(LC, LEs), XL)),
- R0 = xref_utils:xset(reachable(E1, G, []),
+ R0 = xref_utils:xset(reachable(E1, G, []),
[{tspec(func), tspec(fun_edge)}]),
true = digraph:delete(G),
-
+
% RL is a set of indirect local calls to exports.
RL = restriction(R0, XL),
% RX is a set of indirect external calls to exports.
@@ -1033,7 +1033,7 @@ inter_graph(X, L, LC, XC, CallAt) ->
?FORMAT("XL=~p~nXEs=~p~nLEs=~p~nE1=~p~nR0=~p~nRL=~p~nRX=~p~nR=~p~n"
"EE=~p~nECallAt1=~p~nECallAt2=~p~nECallAt=~p~n~n",
- [XL, XEs, LEs, E1, R0, RL, RX, R, EE,
+ [XL, XEs, LEs, E1, R0, RL, RX, R, EE,
ECallAt1, ECallAt2, ECallAt]),
{EE, ECallAt}.
@@ -1121,7 +1121,7 @@ remove_erase([], D) ->
do_add_libraries(Path, Verbose, State) ->
message(Verbose, lib_search, []),
- {C, E} = xref_utils:list_path(Path, [?Suffix]),
+ {C, E} = xref_utils:list_path(Path, [?Suffix]),
message(Verbose, done, []),
MDs = to_external(relation_to_family(relation(C))),
%% message(Verbose, lib_check, []),
@@ -1160,23 +1160,23 @@ do_set_up(S, VerboseOpt) ->
Reply.
%% If data has been supplied using add_module/9 (and that is the only
-%% sanctioned way), then DefAt, L, X, LCallAt, XCallAt, CallAt, XC, LC,
-%% and LU are guaranteed to be functions (with all supplied
-%% modules as domain (disregarding unknown modules, that is, modules
+%% sanctioned way), then DefAt, L, X, LCallAt, XCallAt, CallAt, XC, LC,
+%% and LU are guaranteed to be functions (with all supplied
+%% modules as domain (disregarding unknown modules, that is, modules
%% not supplied but hosting unknown functions)).
%% As a consequence, V and E are also functions. V is defined for unknown
%% modules also.
%% UU is also a function (thanks to sofs:family_difference/2...).
-%% XU on the other hand can be a partial function (that is, not defined
+%% XU on the other hand can be a partial function (that is, not defined
%% for all modules). U is derived from XU, so U is also partial.
%% The inverse variables - LC_1, XC_1, E_1 and EE_1 - are all partial.
%% B is also partial.
do_set_up(S) when S#xref.mode =:= functions ->
ModDictList = dict:to_list(S#xref.modules),
- [DefAt0, L, X0, LCallAt, XCallAt, CallAt, LC, XC, LU,
+ [DefAt0, L, X0, LCallAt, XCallAt, CallAt, LC, XC, LU,
EE0, ECallAt, UC, LPredefined,
Mod_DF,Mod_DF_1,Mod_DF_2,Mod_DF_3] = make_families(ModDictList, 18),
-
+
{XC_1, XU, XPredefined} = do_set_up_1(XC),
LC_1 = user_family(union_of_family(LC)),
E_1 = family_union(XC_1, LC_1),
@@ -1206,7 +1206,7 @@ do_set_up(S) when S#xref.mode =:= functions ->
AM = domain(F1),
%% Undef is the union of U0 and Lib:
- {Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} =
+ {Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} =
make_libs(XU, F1, AM, S#xref.library_path, S#xref.libraries),
{B, U} = make_builtins(U0),
X1_B = family_union(X1, B),
@@ -1228,22 +1228,22 @@ do_set_up(S) when S#xref.mode =:= functions ->
%% way to discard calls to local functions in other modules.
EE_conv = converse(union_of_family(EE0)),
EE_exported = restriction(EE_conv, union_of_family(X)),
- EE_local =
+ EE_local =
specification({external, fun({{M1,_,_},{M2,_,_}}) -> M1 =:= M2 end},
EE_conv),
EE_0 = converse(union(EE_local, EE_exported)),
EE_1 = user_family(EE_0),
- EE1 = partition_family({external, fun({{M1,_,_}, _MFA2}) -> M1 end},
+ EE1 = partition_family({external, fun({{M1,_,_}, _MFA2}) -> M1 end},
EE_0),
%% Make sure EE is defined for all modules:
EE = family_union(family_difference(EE0, EE0), EE1),
- IFun =
- fun({Mod,EE_M}, XMods) ->
- IMFun =
+ IFun =
+ fun({Mod,EE_M}, XMods) ->
+ IMFun =
fun(XrefMod) ->
- [NoCalls, NoFunctionCalls,
+ [NoCalls, NoFunctionCalls,
NoFunctions, _NoInter] = XrefMod#xref_mod.info,
- NewInfo = [NoCalls, NoFunctionCalls, NoFunctions,
+ NewInfo = [NoCalls, NoFunctionCalls, NoFunctions,
{no_inter_function_calls,length(EE_M)}],
XrefMod#xref_mod{info = NewInfo}
end,
@@ -1274,11 +1274,11 @@ do_set_up(S) when S#xref.mode =:= functions ->
finish_set_up(S1, Vs);
do_set_up(S) when S#xref.mode =:= modules ->
ModDictList = dict:to_list(S#xref.modules),
- [X0, I0, Mod_DF, Mod_DF_1, Mod_DF_2, Mod_DF_3] =
+ [X0, I0, Mod_DF, Mod_DF_1, Mod_DF_2, Mod_DF_3] =
make_families(ModDictList, 7),
I = union_of_family(I0),
AM = domain(X0),
-
+
{XU, Predefined} = make_predefined(I, AM),
%% Add "hidden" functions to the exports.
X1 = family_union(X0, Predefined),
@@ -1288,8 +1288,8 @@ do_set_up(S) when S#xref.mode =:= modules ->
M2A = make_M2A(ModDictList),
{A2R,A} = make_A2R(S#xref.applications),
R = set(dict:fetch_keys(S#xref.releases)),
-
- ME = projection({external, fun({M1,{M2,_F2,_A2}}) -> {M1,M2} end},
+
+ ME = projection({external, fun({M1,{M2,_F2,_A2}}) -> {M1,M2} end},
family_to_relation(I0)),
ME2AE = multiple_relative_product({M2A, M2A}, ME),
@@ -1298,7 +1298,7 @@ do_set_up(S) when S#xref.mode =:= modules ->
RE = range(AE2RE),
%% Undef is the union of U0 and Lib:
- {_Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} =
+ {_Undef, U0, Lib, Lib_DF, Lib_DF_1, Lib_DF_2, Lib_DF_3} =
make_libs(XU, X1, AM, S#xref.library_path, S#xref.libraries),
{B, U} = make_builtins(U0),
X1_B = family_union(X1, B),
@@ -1312,7 +1312,7 @@ do_set_up(S) when S#xref.mode =:= modules ->
X = family_union(X1, Lib),
Empty = empty_set(),
- Vs = [{'X',X},{'U',U},{'B',B},{'XU',XU},{v,V},
+ Vs = [{'X',X},{'U',U},{'B',B},{'XU',XU},{v,V},
{e,{Empty,Empty}},
{'M',M},{'A',A},{'R',R},
{'AM',AM},{'UM',UM},{'LM',LM},
@@ -1328,10 +1328,10 @@ finish_set_up(S, Vs) ->
S1 = S#xref{variables = T},
%% io:format("~p <= state <= ~p~n", [pack:lsize(S), pack:usize(S)]),
{ok, S1}.
-
+
do_finish_set_up([{Key, Value} | Vs], T) ->
{Type, OType} = var_type(Key),
- Val = #xref_var{name = Key, value = Value, vtype = predef,
+ Val = #xref_var{name = Key, value = Value, vtype = predef,
otype = OType, type = Type},
T1 = dict:store(Key, Val, T),
do_finish_set_up(Vs, T1);
@@ -1362,15 +1362,15 @@ var_type('EE') -> {function, edge};
var_type('LC') -> {function, edge};
var_type('UC') -> {function, edge};
var_type('XC') -> {function, edge};
-var_type('AE') -> {application, edge};
-var_type('ME') -> {module, edge};
+var_type('AE') -> {application, edge};
+var_type('ME') -> {module, edge};
var_type('RE') -> {release, edge};
var_type(_) -> {foo, bar}.
make_families(ModDictList, N) ->
Fun1 = fun({_,XMod}) -> XMod#xref_mod.data end,
Ss = from_sets(map(Fun1, ModDictList)),
- %% io:format("~n~p <= module data <= ~p~n",
+ %% io:format("~n~p <= module data <= ~p~n",
%% [pack:lsize(Ss), pack:usize(Ss)]),
make_fams(N, Ss, []).
@@ -1389,7 +1389,7 @@ make_M2A(ModDictList) ->
make_A2R(ApplDict) ->
AppDict = dict:to_list(ApplDict),
Fun = fun({A,XApp}) -> {A, XApp#xref_app.rel_name} end,
- Appl0 = family(map(Fun, AppDict)),
+ Appl0 = family(map(Fun, AppDict)),
AllApps = domain(Appl0),
Appl = family_to_relation(Appl0),
{Appl, AllApps}.
@@ -1445,13 +1445,13 @@ make_libs(XU, F, AM, LibPath, LibDict) ->
false ->
Libraries = dict:to_list(LibDict),
Lb = restriction(a_function(Libraries), UM),
- MFun = fun({M,XLib}) ->
+ MFun = fun({M,XLib}) ->
#xref_lib{dir = Dir} = XLib,
xref_utils:module_filename(Dir, M)
end,
map(MFun, to_external(Lb))
end,
- Fun = fun(FileName, Deprs) ->
+ Fun = fun(FileName, Deprs) ->
case beam_lib:chunks(FileName, [exports, attributes]) of
{ok, {M, [{exports,X}, {attributes,A}]}} ->
Exports = mfa_exports(X, A, M),
@@ -1496,14 +1496,14 @@ user_family(R) ->
partition_family({external, fun({_MFA1, {M2,_,_}}) -> M2 end}, R).
do_variables(State) ->
- Fun = fun({Name, #xref_var{vtype = user}}, {P,U}) ->
+ Fun = fun({Name, #xref_var{vtype = user}}, {P,U}) ->
{P,[Name | U]};
- ({Name, #xref_var{vtype = predef}}, A={P,U}) ->
+ ({Name, #xref_var{vtype = predef}}, A={P,U}) ->
case atom_to_list(Name) of
[H|_] when H>= $a, H=<$z -> A;
_Else -> {[Name | P], U}
end;
- ({{tmp, V}, _}, A) ->
+ ({{tmp, V}, _}, A) ->
io:format("Bug in ~p: temporary ~p~n", [?MODULE, V]), A;
(_V, A) -> A
end,
@@ -1565,7 +1565,7 @@ do_info(S, libraries) ->
map(fun({_L,XLib}) -> lib_info(XLib) end, D);
do_info(_S, I) ->
error({no_such_info, I}).
-
+
do_info(S, Type, E) when is_atom(E) ->
do_info(S, Type, [E]);
do_info(S, modules, Modules0) when is_list(Modules0) ->
@@ -1598,7 +1598,7 @@ find_info([E | Es], Dict, Error) ->
{ok, X} ->
[X | find_info(Es, Dict, Error)]
end;
-find_info([], _Dict, _Error) ->
+find_info([], _Dict, _Error) ->
[].
%% -> {[{AppName, RelName}], [{RelName, XApp}]}
@@ -1618,7 +1618,7 @@ rel_apps(S) ->
rel_apps_sums(AR, RRA0, S) ->
AppMods = app_mods(S), % [{AppName, XMod}]
RRA1 = relation_to_family(relation(RRA0)),
- RRA = inverse(substitution(1, RRA1)),
+ RRA = inverse(substitution(1, RRA1)),
%% RRA is [{RelName,{RelName,[XApp]}}]
RelMods = relative_product1(relation(AR), relation(AppMods)),
RelAppsMods = relative_product1(RRA, RelMods),
@@ -1630,7 +1630,7 @@ rel_apps_sums(AR, RRA0, S) ->
%% -> [{AppName, XMod}]
app_mods(S) ->
D = sort(dict:to_list(S#xref.modules)),
- Fun = fun({_M,XMod}, Acc) ->
+ Fun = fun({_M,XMod}, Acc) ->
case XMod#xref_mod.app_name of
[] -> Acc;
[AppName] -> [{AppName, XMod} | Acc]
@@ -1639,7 +1639,7 @@ app_mods(S) ->
foldl(Fun, [], D).
mod_info(XMod) ->
- #xref_mod{name = M, app_name = AppName, builtins = BuiltIns,
+ #xref_mod{name = M, app_name = AppName, builtins = BuiltIns,
dir = Dir, info = Info} = XMod,
App = sup_info(AppName),
{M, [{application, App}, {builtins, BuiltIns}, {directory, Dir} | Info]}.
@@ -1649,7 +1649,7 @@ app_info({AppName, ModSums}, S) ->
#xref_app{rel_name = RelName, vsn = Vsn, dir = Dir} = XApp,
Release = sup_info(RelName),
{AppName, [{directory,Dir}, {release, Release}, {version,Vsn} | ModSums]}.
-
+
rel_info({{RelName, XApps}, ModSums}, S) ->
NoApps = length(XApps),
XRel = dict:fetch(RelName, S#xref.releases),
@@ -1678,16 +1678,16 @@ no_sum(S, L) when S#xref.mode =:= modules ->
[{no_analyzed_modules, length(L)}].
no_sum([XMod | D], C0, UC0, LC0, XC0, UFC0, L0, X0, EV0, NoM) ->
- [{no_calls, {C,UC}},
+ [{no_calls, {C,UC}},
{no_function_calls, {LC,XC,UFC}},
{no_functions, {L,X}},
{no_inter_function_calls, EV}] = XMod#xref_mod.info,
no_sum(D, C0+C, UC0+UC, LC0+LC, XC0+XC, UFC0+UFC, L0+L, X0+X, EV0+EV, NoM);
no_sum([], C, UC, LC, XC, UFC, L, X, EV, NoM) ->
[{no_analyzed_modules, NoM},
- {no_calls, {C,UC}},
+ {no_calls, {C,UC}},
{no_function_calls, {LC,XC,UFC}},
- {no_functions, {L,X}},
+ {no_functions, {L,X}},
{no_inter_function_calls, EV}].
%% -> ok | throw(Error)
@@ -1712,20 +1712,20 @@ warnings(Flag, Message, [F | Fs]) ->
%% pack(term()) -> term()
%%
%% The identify function. The returned term does not use more heap
-%% than the given term. Tuples that are equal (=:=/2) are made
+%% than the given term. Tuples that are equal (=:=/2) are made
%% "the same".
%%
%% The process dictionary is used because it seems to be faster than
%% anything else right now...
%%
%pack(T) -> T;
-pack(T) ->
+pack(T) ->
PD = erase(),
NT = pack1(T),
%% true = T =:= NT,
%% io:format("erasing ~p elements...~n", [length(erase())]),
erase(), % wasting heap (and time)...
- map(fun({K,V}) -> put(K, V) end, PD),
+ foreach(fun({K,V}) -> put(K, V) end, PD),
NT.
pack1(C) when not is_tuple(C), not is_list(C) ->
diff --git a/lib/tools/src/xref_compiler.erl b/lib/tools/src/xref_compiler.erl
index 67ac8c617d..c80eb0e669 100644
--- a/lib/tools/src/xref_compiler.erl
+++ b/lib/tools/src/xref_compiler.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%
%%
@@ -37,15 +37,15 @@
-export([format_error/1]).
--import(lists,
+-import(lists,
[concat/1, foldl/3, nthtail/2, reverse/1, sort/1, sublist/2]).
-import(sofs,
[composite/2, difference/2, empty_set/0, from_term/1,
intersection/2, is_empty_set/1, multiple_relative_product/2,
projection/2, relation/1, relation_to_family/1,
- restriction/2, substitution/2, to_external/1, union/2,
- union_of_family/1]).
+ restriction/2, specification/2, substitution/2,
+ to_external/1, union/2, union_of_family/1]).
%%
%% Exported functions
@@ -75,7 +75,7 @@ compile(Chars, Table) ->
{error, Info, Line} ->
error({parse_error, Line, Info})
end.
-
+
format_error({error, Module, Error}) ->
Module:format_error(Error);
format_error({parse_error, Line, Error}) ->
@@ -115,7 +115,7 @@ statements([Stmt={assign, VarType, Name, E} | Stmts0], Table, L, UV) ->
throw_error({variable_reassigned, xref_parser:t2s(Stmt)});
error ->
{Type, OType, NewE} = t_expr(E, Table),
- Val = #xref_var{name = Name, vtype = VarType,
+ Val = #xref_var{name = Name, vtype = VarType,
otype = OType, type = Type},
NewTable = dict:store(Name, Val, Table),
Stmts = if Stmts0 =:= [] -> [{variable, Name}]; true -> Stmts0 end,
@@ -128,9 +128,9 @@ statements([Expr], Table, L, UV) ->
E1 = un_familiarize(Type, OType, NewE),
NE = case {Type, OType} of
%% Edges with empty sets of line numbers are removed.
- {{line, _}, edge} ->
+ {{line, _}, edge} ->
{relation_to_family, E1};
- {_Type, edge_closure} ->
+ {_Type, edge_closure} ->
%% Fake a closure usage, just to make sure it is destroyed.
E2 = {fun graph_access/2, E1, E1},
{fun(_E) -> 'closure()' end, E2};
@@ -163,7 +163,7 @@ t_expr(E, Table) ->
%%% Constant = atom() | {atom(), atom()} | MFA | {MFA, MFA}
%%% Call = atom() % function in the sofs module
%%% | fun()
-%%% Type = {line, LineType} | function | module | application | release
+%%% Type = {line, LineType} | function | module | application | release
%%% | number
%%% LineType = line | local_call | external_call | export_call | all_line_call
%%% VarType = predef | user | tmp
@@ -182,7 +182,7 @@ check_expr({variable, Name}, Table) ->
case dict:find(Name, Table) of
{ok, #xref_var{vtype = VarType, otype = OType, type = Type}} ->
V0 = {variable, {VarType, Name}},
- V = case {VarType, Type, OType} of
+ V = case {VarType, Type, OType} of
{predef, release, _} -> V0;
{predef, application, _} -> V0;
{predef, module, _} -> V0;
@@ -212,7 +212,7 @@ check_expr(Expr={set, SOp, E}, Table) ->
{edge_set, domain} -> vertex_set;
{edge_set, weak} -> edge_set;
{edge_set, strict} -> edge_set;
- _ ->
+ _ ->
throw_error({type_error, xref_parser:t2s(Expr)})
end,
Op = set_op(SOp),
@@ -223,10 +223,10 @@ check_expr(Expr={graph, Op, E}, Table) ->
case Type of
{line, _LineType} ->
throw_error({type_error, xref_parser:t2s(Expr)});
- _Else ->
+ _Else ->
ok
end,
- OType =
+ OType =
case {NOType, Op} of
{edge, components} -> vertex_set;
{edge, condensation} -> edge_set;
@@ -237,7 +237,7 @@ check_expr(Expr={graph, Op, E}, Table) ->
%% Neither need nor want these ones:
%% {edge_set, closure} -> edge_set_closure;
%% {edge_set, components} -> vertex_set_set;
- _ ->
+ _ ->
throw_error({type_error, xref_parser:t2s(Expr)})
end,
E2 = {convert, NOType, edge_closure, E1},
@@ -271,10 +271,10 @@ check_expr(Expr={set, SOp, E1, E2}, Table) ->
number ->
{expr, number, number, {call, ari_op(SOp), NE1, NE2}};
_Else -> % set
- {Type, NewE1, NewE2} =
+ {Type, NewE1, NewE2} =
case {type_ord(Type1), type_ord(Type2)} of
{T1, T2} when T1 =:= T2 ->
- %% Example: if Type1 = {line, line} and
+ %% Example: if Type1 = {line, line} and
%% Type2 = {line, export_line}, then this is not
%% correct, but works:
{Type1, NE1, NE2};
@@ -296,7 +296,7 @@ check_expr(Expr={restr, ROp, E1, E2}, Table) ->
throw_error({type_error, xref_parser:t2s(Expr)});
{_Type1, {line, _LineType2}} ->
throw_error({type_error, xref_parser:t2s(Expr)});
- _ ->
+ _ ->
ok
end,
case {OType1, OType2} of
@@ -307,14 +307,14 @@ check_expr(Expr={restr, ROp, E1, E2}, Table) ->
{edge, vertex} ->
restriction(ROp, E1, Type1, NE1, Type2, NE2);
{edge_closure, vertex} when ROp =:= '|||' ->
- {expr, _, _, R1} =
+ {expr, _, _, R1} =
closure_restriction('|', Type1, Type2, OType2, NE1, NE2),
- {expr, _, _, R2} =
+ {expr, _, _, R2} =
closure_restriction('||', Type1, Type2, OType2, NE1, NE2),
{expr, Type1, edge, {call, intersection, R1, R2}};
- {edge_closure, vertex} ->
+ {edge_closure, vertex} ->
closure_restriction(ROp, Type1, Type2, OType2, NE1, NE2);
- _ ->
+ _ ->
throw_error({type_error, xref_parser:t2s(Expr)})
end;
check_expr(Expr={path, E1, E2}, Table) ->
@@ -330,7 +330,7 @@ check_expr(Expr={path, E1, E2}, Table) ->
end,
E2b = {convert, OType2, Type2, Type1, E2a},
{OType1, NE1} = path_arg(OType1a, E1a),
- NE2 = case {OType1, OType2} of
+ NE2 = case {OType1, OType2} of
{path, edge} -> {convert, OType2, edge_closure, E2b};
{path, edge_closure} when Type1 =:= Type2 -> E2b;
_ -> throw_error({type_error, xref_parser:t2s(Expr)})
@@ -347,7 +347,7 @@ check_expr({regexpr, RExpr, Type0}, _Table) ->
release -> 'R'
end,
Var = {variable, {predef, V}},
- Call = {call, fun(E, V2) -> xref_utils:regexpr(E, V2) end,
+ Call = {call, fun(E, V2) -> xref_utils:regexpr(E, V2) end,
{constants, RExpr}, Var},
{expr, Type, vertex, Call};
check_expr(C={constant, _Type, _OType, _C}, Table) ->
@@ -368,15 +368,15 @@ check_conversion(OType, Type1, Type2, Expr) ->
end.
%% Allowed conversions.
-conversions(_OType, {line, LineType}, {line, LineType}) -> ok;
+conversions(_OType, {line, LineType}, {line, LineType}) -> ok;
conversions(edge, {line, _}, {line, all_line_call}) -> ok;
-conversions(edge, From, {line, Line})
+conversions(edge, From, {line, Line})
when is_atom(From), Line =/= all_line_call -> ok;
conversions(vertex, From, {line, line}) when is_atom(From) -> ok;
conversions(vertex, From, To) when is_atom(From), is_atom(To) -> ok;
conversions(edge, From, To) when is_atom(From), is_atom(To) -> ok;
%% "Extra":
-conversions(edge, {line, Line}, To)
+conversions(edge, {line, Line}, To)
when is_atom(To), Line =/= all_line_call -> ok;
conversions(vertex, {line, line}, To) when is_atom(To) -> ok;
conversions(_OType, _From, _To) -> not_ok.
@@ -399,7 +399,7 @@ ari_op(difference) -> fun(X, Y) -> X - Y end.
restriction(ROp, E1, Type1, NE1, Type2, NE2) ->
{Column, _} = restr_op(ROp),
- case NE1 of
+ case NE1 of
{call, union_of_family, _E} when ROp =:= '|' ->
restriction(Column, Type1, E1, Type2, NE2);
{call, union_of_family, _E} when ROp =:= '||' ->
@@ -455,8 +455,8 @@ check_constants(Cs=[C={constant, Type0, OType, _Con} | Cs1], Table) ->
E = function_vertices_to_family(Type, OType, {constants, S}),
{expr, Type, OType, E};
[{Type1, [C1|_]}, {Type2, [C2|_]} | _] ->
- throw_error({type_mismatch,
- make_vertex(Type1, C1),
+ throw_error({type_mismatch,
+ make_vertex(Type1, C1),
make_vertex(Type2, C2)})
end.
@@ -467,7 +467,7 @@ check_mix([C={constant, Type, OType, _Con} | Cs], Type0, OType, _C0)
check_mix(Cs, Type, OType, C);
check_mix([C | _], _Type0, _OType0, C0) ->
throw_error({type_mismatch, xref_parser:t2s(C0), xref_parser:t2s(C)});
-check_mix([], _Type0, _OType0, _C0) ->
+check_mix([], _Type0, _OType0, _C0) ->
ok.
split(Types, Cs, Table) ->
@@ -478,11 +478,11 @@ split([Type | Types], Vs, AllSoFar, _Type, Table, L) ->
S0 = known_vertices(Type, Vs, Table),
S = difference(S0, AllSoFar),
case is_empty_set(S) of
- true ->
+ true ->
split(Types, Vs, AllSoFar, Type, Table, L);
- false ->
+ false ->
All = union(AllSoFar, S0),
- split(Types, Vs, All, Type, Table,
+ split(Types, Vs, All, Type, Table,
[{Type, to_external(S)} | L])
end;
split([], Vs, All, Type, _Table, L) ->
@@ -491,7 +491,7 @@ split([], Vs, All, Type, _Table, L) ->
[C|_] -> throw_error({unknown_constant, make_vertex(Type, C)})
end.
-make_vertex(Type, C) ->
+make_vertex(Type, C) ->
xref_parser:t2s({constant, Type, vertex, C}).
constant_vertices([{constant, _Type, edge, {A,B}} | Cs], L) ->
@@ -504,7 +504,7 @@ constant_vertices([], L) ->
known_vertices('Fun', Cs, T) ->
M = projection(1, Cs),
F = union_of_family(restriction(fetch_value(v, T), M)),
- intersection(Cs, F);
+ union(bifs(Cs), intersection(Cs, F));
known_vertices('Mod', Cs, T) ->
intersection(Cs, fetch_value('M', T));
known_vertices('App', Cs, T) ->
@@ -512,6 +512,11 @@ known_vertices('App', Cs, T) ->
known_vertices('Rel', Cs, T) ->
intersection(Cs, fetch_value('R', T)).
+bifs(Cs) ->
+ specification({external,
+ fun({M,F,A}) -> xref_utils:is_builtin(M, F, A) end},
+ Cs).
+
function_vertices_to_family(function, vertex, E) ->
{call, partition_family, 1, E};
function_vertices_to_family(_Type, _OType, E) ->
@@ -567,11 +572,11 @@ convert(E, OType, FromType, ToType) ->
general(_ObjectType, FromType, ToType, X) when FromType =:= ToType ->
X;
-general(edge, {line, _LineType}, ToType, LEs) ->
+general(edge, {line, _LineType}, ToType, LEs) ->
VEs = {projection, ?Q({external, fun({V1V2,_Ls}) -> V1V2 end}), LEs},
general(edge, function, ToType, VEs);
general(edge, function, ToType, VEs) ->
- MEs = {projection,
+ MEs = {projection,
?Q({external, fun({{M1,_,_},{M2,_,_}}) -> {M1,M2} end}),
VEs},
general(edge, module, ToType, MEs);
@@ -580,7 +585,7 @@ general(edge, module, ToType, MEs) ->
general(edge, application, ToType, AEs);
general(edge, application, release, AEs) ->
{image, {get, ae}, AEs};
-general(vertex, {line, _LineType}, ToType, L) ->
+general(vertex, {line, _LineType}, ToType, L) ->
V = {partition_family, ?Q(1), {domain, L}},
general(vertex, function, ToType, V);
general(vertex, function, ToType, V) ->
@@ -595,18 +600,18 @@ general(vertex, application, release, A) ->
special(_ObjectType, FromType, ToType, X) when FromType =:= ToType ->
X;
special(edge, {line, _LineType}, {line, all_line_call}, Calls) ->
- {put, ?T(mods),
- {projection,
- ?Q({external, fun({{{M1,_,_},{M2,_,_}},_}) -> {M1,M2} end}),
+ {put, ?T(mods),
+ {projection,
+ ?Q({external, fun({{{M1,_,_},{M2,_,_}},_}) -> {M1,M2} end}),
Calls},
- {put, ?T(def_at),
+ {put, ?T(def_at),
{union, {image, {get, def_at},
- {union, {domain, {get, ?T(mods)}},
+ {union, {domain, {get, ?T(mods)}},
{range, {get, ?T(mods)}}}}},
{fun funs_to_lines/2,
{get, ?T(def_at)}, Calls}}};
special(edge, function, {line, LineType}, VEs) ->
- Var = if
+ Var = if
LineType =:= line -> call_at;
LineType =:= export_call -> e_call_at;
LineType =:= local_call -> l_call_at;
@@ -615,9 +620,9 @@ special(edge, function, {line, LineType}, VEs) ->
line_edges(VEs, Var);
special(edge, module, ToType, MEs) ->
VEs = {image,
- {projection,
+ {projection,
?Q({external, fun(FE={{M1,_,_},{M2,_,_}}) -> {{M1,M2},FE} end}),
- {union,
+ {union,
{image, {get, e},
{projection, ?Q({external, fun({M1,_M2}) -> M1 end}), MEs}}}},
MEs},
@@ -629,7 +634,7 @@ special(edge, release, ToType, REs) ->
AEs = {inverse_image, {get, ae}, REs},
special(edge, application, ToType, AEs);
special(vertex, function, {line, _LineType}, V) ->
- {restriction,
+ {restriction,
{union_of_family, {restriction, {get, def_at}, {domain, V}}},
{union_of_family, V}};
special(vertex, module, ToType, M) ->
@@ -643,15 +648,15 @@ special(vertex, release, ToType, R) ->
special(vertex, application, ToType, A).
line_edges(VEs, CallAt) ->
- {put, ?T(ves), VEs,
- {put, ?T(m1),
- {projection, ?Q({external, fun({{M1,_,_},_}) -> M1 end}),
+ {put, ?T(ves), VEs,
+ {put, ?T(m1),
+ {projection, ?Q({external, fun({{M1,_,_},_}) -> M1 end}),
{get, ?T(ves)}},
{image, {projection, ?Q({external, fun(C={VV,_L}) -> {VV,C} end}),
{union, {image, {get, CallAt}, {get, ?T(m1)}}}},
{get, ?T(ves)}}}}.
-%% {(((v1,l1),(v2,l2)),l) :
+%% {(((v1,l1),(v2,l2)),l) :
%% (v1,l1) in DefAt and (v2,l2) in DefAt and ((v1,v2),L) in CallAt}
funs_to_lines(DefAt, CallAt) ->
T1 = multiple_relative_product({DefAt, DefAt}, projection(1, CallAt)),
@@ -765,7 +770,7 @@ save_vars([], _D, Vs, UVs, L) ->
%% Traverses the expression again, this time using more or less the
%% inverse of the table created by find_nodes. The first time a node
-%% is visited, its children are traversed, the following times a
+%% is visited, its children are traversed, the following times a
%% get instructions are inserted (using the saved value).
make_instructions(N, UserVars, D) ->
{D1, Is0} = make_instrs(N, D, []),
@@ -777,9 +782,9 @@ make_instructions(N, UserVars, D) ->
make_more_instrs([UV | UVs], D, Is) ->
case dict:find(UV, D) of
- error ->
+ error ->
make_more_instrs(UVs, D, Is);
- _Else ->
+ _Else ->
{ND, NIs} = make_instrs(UV, D, Is),
make_more_instrs(UVs, ND, [pop | NIs])
end;
@@ -844,17 +849,17 @@ evaluate([{quote, Val} | P], T, S) ->
evaluate(P, T, [Val | S]);
evaluate([{get, Var} | P], T, S) when is_atom(Var) -> % predefined
Value = fetch_value(Var, T),
- Val = case Value of
+ Val = case Value of
{R, _} -> R; % relation
_ -> Value % simple set
end,
- evaluate(P, T, [Val | S]);
+ evaluate(P, T, [Val | S]);
evaluate([{get, {inverse, Var}} | P], T, S) -> % predefined, inverse
{_, R} = fetch_value(Var, T),
- evaluate(P, T, [R | S]);
+ evaluate(P, T, [R | S]);
evaluate([{get, {user, Var}} | P], T, S) ->
Val = fetch_value(Var, T),
- evaluate(P, T, [Val | S]);
+ evaluate(P, T, [Val | S]);
evaluate([{get, Var} | P], T, S) -> % tmp
evaluate(P, T, [dict:fetch(Var, T) | S]);
evaluate([{save, Var={tmp, _}} | P], T, S=[Val | _]) ->
@@ -862,7 +867,7 @@ evaluate([{save, Var={tmp, _}} | P], T, S=[Val | _]) ->
evaluate(P, dict:store(Var, Val, T1), S);
evaluate([{save, {user, Name}} | P], T, S=[Val | _]) ->
#xref_var{vtype = user, otype = OType, type = Type} = dict:fetch(Name, T),
- NewVar = #xref_var{name = Name, value = Val,
+ NewVar = #xref_var{name = Name, value = Val,
vtype = user, otype = OType, type = Type},
T1 = update_graph_counter(Val, +1, T),
NT = dict:store(Name, NewVar, T1),
@@ -889,7 +894,7 @@ update_graph_counter(Value, Inc, T) ->
error when Inc =:= 1 ->
dict:store(Value, 1, T)
end;
- _EXIT ->
+ _EXIT ->
T
end.
diff --git a/lib/tools/src/xref_reader.erl b/lib/tools/src/xref_reader.erl
index db755c31d8..d22f0df164 100644
--- a/lib/tools/src/xref_reader.erl
+++ b/lib/tools/src/xref_reader.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_reader).
@@ -22,7 +22,7 @@
-import(lists, [keysearch/3, member/2, reverse/1]).
--record(xrefr,
+-record(xrefr,
{module=[],
function=[],
def_at=[],
@@ -59,15 +59,15 @@
module(Module, Forms, CollectBuiltins, X, DF) ->
Attrs = [{Attr,V} || {attribute,_Line,Attr,V} <- Forms],
IsAbstract = xref_utils:is_abstract_module(Attrs),
- S = #xrefr{module = Module, builtins_too = CollectBuiltins,
+ S = #xrefr{module = Module, builtins_too = CollectBuiltins,
is_abstr = IsAbstract, x = X, df = DF},
forms(Forms, S).
forms([F | Fs], S) ->
S1 = form(F, S),
forms(Fs, S1);
-forms([], S) ->
- #xrefr{module = M, def_at = DefAt,
+forms([], S) ->
+ #xrefr{module = M, def_at = DefAt,
l_call_at = LCallAt, x_call_at = XCallAt,
el = LC, ex = XC, x = X, df = Depr,
lattrs = AL, xattrs = AX, battrs = B, unresolved = U} = S,
@@ -75,7 +75,7 @@ forms([], S) ->
{ok, M, {DefAt, LCallAt, XCallAt, LC, XC, X, Attrs, Depr}, U}.
form({attribute, Line, xref, Calls}, S) -> % experimental
- #xrefr{module = M, function = Fun,
+ #xrefr{module = M, function = Fun,
lattrs = L, xattrs = X, battrs = B} = S,
attr(Calls, Line, M, Fun, L, X, B, S);
form({attribute, _Line, _Attr, _Val}, S) ->
@@ -110,12 +110,12 @@ clauses([{clause, _Line, _H, G, B} | Cs], FunVars, Matches, S) ->
S2 = expr(B, S1),
S3 = S2#xrefr{funvars = FunVars, matches = Matches},
clauses(Cs, S3);
-clauses([], _FunVars, _Matches, S) ->
+clauses([], _FunVars, _Matches, S) ->
S.
attr([E={From, To} | As], Ln, M, Fun, AL, AX, B, S) ->
case mfa(From, M) of
- {_, _, MFA} when MFA =:= Fun; [] =:= Fun ->
+ {_, _, MFA} when MFA =:= Fun; [] =:= Fun ->
attr(From, To, Ln, M, Fun, AL, AX, B, S, As, E);
{_, _, _} ->
attr(As, Ln, M, Fun, AL, AX, [E | B], S);
@@ -164,7 +164,7 @@ expr({call, Line,
%% Added in R10B-6. M:F/A.
expr({'fun', Line, {function, Mod, Fun, Arity}}, S);
expr({'fun', Line, {function, Mod, Name, Arity}}, S) ->
- %% Added in R10B-6. M:F/A.
+ %% Added in R10B-6. M:F/A.
As = lists:duplicate(Arity, {atom, Line, foo}),
external_call(Mod, Name, As, Line, false, S);
expr({'fun', Line, {function, Name, Arity}, _Extra}, S) ->
@@ -183,7 +183,7 @@ expr({call, Line, {remote, _Line, Mod, Name}, As}, S) ->
expr({call, Line, F, As}, S) ->
external_call(erlang, apply, [F, list2term(As)], Line, true, S);
expr({match, _Line, {var,_,Var}, {'fun', _, {clauses, Cs}, _Extra}}, S) ->
- %% This is what is needed in R7 to avoid warnings for the functions
+ %% This is what is needed in R7 to avoid warnings for the functions
%% that are passed around by the "expansion" of list comprehension.
S1 = S#xrefr{funvars = [Var | S#xrefr.funvars]},
clauses(Cs, S1);
@@ -192,6 +192,14 @@ expr({match, _Line, {var,_,Var}, E}, S) ->
%% Args = [A,B], apply(m, f, Args)
S1 = S#xrefr{matches = [{Var, E} | S#xrefr.matches]},
expr(E, S1);
+expr({op, _Line, 'orelse', Op1, Op2}, S) ->
+ expr([Op1, Op2], S);
+expr({op, _Line, 'andalso', Op1, Op2}, S) ->
+ expr([Op1, Op2], S);
+expr({op, Line, Op, Operand1, Operand2}, S) ->
+ external_call(erlang, Op, [Operand1, Operand2], Line, false, S);
+expr({op, Line, Op, Operand}, S) ->
+ external_call(erlang, Op, [Operand], Line, false, S);
expr(T, S) when is_tuple(T) ->
expr(tuple_to_list(T), S);
expr([E | Es], S) ->
@@ -241,13 +249,13 @@ external_call(Mod, Fun, ArgsList, Line, X, S) ->
_Else -> % apply2, 1 or 2
check_funarg(W, ArgsList, Line, S1)
end.
-
+
eval_args(Mod, Fun, ArgsTerm, Line, S, ArgsList, Extra) ->
{IsSimpleCall, M, F} = mod_fun(Mod, Fun),
case term2list(ArgsTerm, [], S) of
undefined ->
S1 = unresolved(M, F, -1, Line, S),
- expr(ArgsList, S1);
+ expr(ArgsList, S1);
ArgsList2 when not IsSimpleCall ->
S1 = unresolved(M, F, length(ArgsList2), Line, S),
expr(ArgsList, S1);
@@ -288,14 +296,14 @@ fun_args(apply2, [FunArg, Args]) -> {FunArg, Args};
fun_args(1, [FunArg | Args]) -> {FunArg, Args};
fun_args(2, [_Node, FunArg | Args]) -> {FunArg, Args}.
-list2term([A | As]) ->
+list2term([A | As]) ->
{cons, 0, A, list2term(As)};
-list2term([]) ->
+list2term([]) ->
{nil, 0}.
term2list({cons, _Line, H, T}, L, S) ->
term2list(T, [H | L], S);
-term2list({nil, _Line}, L, _S) ->
+term2list({nil, _Line}, L, _S) ->
reverse(L);
term2list({var, _, Var}, L, S) ->
case keysearch(Var, 1, S#xrefr.matches) of
@@ -332,11 +340,11 @@ handle_call(Locality, To0, Line, S, IsUnres) ->
true ->
S
end,
- case Locality of
- local ->
+ case Locality of
+ local ->
S1#xrefr{el = [Call | S1#xrefr.el],
l_call_at = [CallAt | S1#xrefr.l_call_at]};
- external ->
+ external ->
S1#xrefr{ex = [Call | S1#xrefr.ex],
x_call_at = [CallAt | S1#xrefr.x_call_at]}
end.
diff --git a/lib/tools/test/xref_SUITE.erl b/lib/tools/test/xref_SUITE.erl
index a7855b0bb9..f9d062ef85 100644
--- a/lib/tools/test/xref_SUITE.erl
+++ b/lib/tools/test/xref_SUITE.erl
@@ -39,11 +39,11 @@
-export([all/1, init/1, fini/1]).
-export([xref/1,
- addrem/1, convert/1, intergraph/1, lines/1, loops/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,
+ 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]).
@@ -82,7 +82,7 @@ init(Conf) when is_list(Conf) ->
?line ok = erl_tar:extract(TarFile, [compressed]),
?line ok = file:delete(TarFile),
[{copy_dir, CopyDir} | Conf].
-
+
fini(Conf) when is_list(Conf) ->
%% Nothing.
Conf.
@@ -120,7 +120,7 @@ addrem(Conf) when is_list(Conf) ->
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,
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
XC_m1, LC_m1),
D2 = {F2,7},
@@ -132,7 +132,7 @@ addrem(Conf) when is_list(Conf) ->
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,
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
XC_m2, LC_m2),
?line S5 = set_up(S2),
@@ -142,7 +142,7 @@ addrem(Conf) when is_list(Conf) ->
?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),
@@ -186,7 +186,7 @@ convert(Conf) when is_list(Conf) ->
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,
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
XC_m1, LC_m1),
D2 = {F2,7},
@@ -200,7 +200,7 @@ convert(Conf) when is_list(Conf) ->
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,
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
XC_m2, LC_m2),
D4 = {F4,6},
@@ -213,7 +213,7 @@ convert(Conf) when is_list(Conf) ->
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,
+ ?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]},
@@ -303,7 +303,7 @@ convert(Conf) when is_list(Conf) ->
?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]]),
+ ?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),
@@ -323,7 +323,7 @@ intergraph(Conf) when is_list(Conf) ->
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},
@@ -339,7 +339,7 @@ intergraph(Conf) when is_list(Conf) ->
E5 = {F4,F2},
E6 = {F5,F4},
E7 = {F4,F5},
-
+
E8 = {F6,F7},
E9 = {F7,F8},
E10 = {F8,F1}, % X
@@ -363,9 +363,9 @@ intergraph(Conf) when is_list(Conf) ->
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,
+ ?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},
@@ -380,7 +380,7 @@ intergraph(Conf) when is_list(Conf) ->
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,
+ ?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]},
@@ -397,13 +397,13 @@ intergraph(Conf) when is_list(Conf) ->
?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)",
+ ?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]}],
+ ?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)",
+ ?line {ok, _} = eval("(XXL)(ELin)(ELin)(EE | m2)",
[{{D6,D1},[8,11,12]}], S),
%% Combining graphs (equal or different):
@@ -420,15 +420,15 @@ intergraph(Conf) when is_list(Conf) ->
?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]),
+ ?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]),
+ ?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}]),
+ ?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:
@@ -438,7 +438,7 @@ intergraph(Conf) when is_list(Conf) ->
%% 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)",
+ ?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),
@@ -449,7 +449,7 @@ 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},
@@ -464,14 +464,14 @@ lines(Conf) when is_list(Conf) ->
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],
@@ -480,7 +480,7 @@ lines(Conf) when is_list(Conf) ->
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,
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
XC_m1, LC_m1),
DefAt_m2 = [D4],
@@ -491,9 +491,9 @@ lines(Conf) when is_list(Conf) ->
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,
+ ?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]},
@@ -509,10 +509,10 @@ lines(Conf) when is_list(Conf) ->
{{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]}],
+ {{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}],
+ [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]},
@@ -567,7 +567,7 @@ lines(Conf) when is_list(Conf) ->
loops(suite) -> [];
loops(doc) -> ["More Inter Call Graph, loops and \"unusual\" cases"];
loops(Conf) when is_list(Conf) ->
- S0 = new(),
+ S0 = new(),
F1 = {m1,f1,1}, % X
F2 = {m1,f2,2},
@@ -582,7 +582,7 @@ loops(Conf) when is_list(Conf) ->
E3 = {F3,F4},
E4 = {F4,F5},
E5 = {F5,F3}, % X
-
+
D1 = {F1,1},
D2 = {F2,2},
D3 = {F3,3},
@@ -598,7 +598,7 @@ loops(Conf) when is_list(Conf) ->
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,
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
XC_m1, LC_m1),
?line S = set_up(S1),
@@ -659,16 +659,16 @@ modules(Conf) when is_list(Conf) ->
?line {ok, y} = compile:file(Y, [debug_info, {outdir,EB1_1}]),
?line {ok, S0} = xref_base:new([{xref_mode, modules}]),
- ?line {ok, release2, S1} =
+ ?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}}, _} =
+ ?line {{error, _, {unavailable_analysis, locals_not_used}}, _} =
xref_base:analyze(S, locals_not_used),
- ?line {{error, _, {unavailable_analysis, {call, foo}}}, _} =
+ ?line {{error, _, {unavailable_analysis, {call, foo}}}, _} =
xref_base:analyze(S, {call, foo}),
- ?line {{error, _, {unavailable_analysis, {use, 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)),
@@ -681,7 +681,7 @@ modules(Conf) when is_list(Conf) ->
ok.
files(suite) ->
- [add, default, info, lib, read, read2, remove, replace, update,
+ [add, default, info, lib, read, read2, remove, replace, update,
deprecated, trycatch, abstract_modules, fun_mfa, qlc].
add(suite) -> [];
@@ -708,7 +708,7 @@ add(Conf) when is_list(Conf) ->
{unix, _} ->
?line make_udir(UDir),
?line make_ufile(UFile);
- _ ->
+ _ ->
true
end,
@@ -743,20 +743,20 @@ add(Conf) when is_list(Conf) ->
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} =
+ ?line {ok, S1} =
xref_base:set_default(S, [{verbose,false}, {warnings, false}]),
?line case os:type() of
{unix, _} ->
- ?line {error, _, {file_error, _, _}} =
+ ?line {error, _, {file_error, _, _}} =
xref_base:add_release(S, UDir);
_ ->
true
end,
- ?line {error, _, {file_error, _, _}} =
+ ?line {error, _, {file_error, _, _}} =
xref_base:add_release(S, fname(["/a/b/c/d/e/f","__foo"])),
- ?line {ok, release2, S2} =
+ ?line {ok, release2, S2} =
xref_base:add_release(S1, Dir, [{name,release2}]),
- ?line {error, _, {module_clash, {x, _, _}}} =
+ ?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),
@@ -764,11 +764,11 @@ add(Conf) when is_list(Conf) ->
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"),
+ ?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, _, _}} =
+ ?line {error, _, {file_error, _, _}} =
xref_base:add_directory(S6, UDir);
_ ->
true
@@ -803,7 +803,7 @@ default(Conf) when is_list(Conf) ->
xref_base:set_default(S, [not_an_option]),
?line D = xref_base:get_default(S),
- ?line [{builtins,false},{recurse,false},{verbose,false},{warnings,true}] =
+ ?line [{builtins,false},{recurse,false},{verbose,false},{warnings,true}] =
D,
?line ok = xref_base:delete(S),
@@ -831,7 +831,7 @@ info(Conf) when is_list(Conf) ->
?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}} =
+ ?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}]),
@@ -845,9 +845,9 @@ info(Conf) when is_list(Conf) ->
?line [{rel2,_}] = xref:info(s, releases, rel2),
?line {error, _, {no_such_library, foo}} = xref:info(s, libraries, [foo]),
- ?line {ok, lib1} =
+ ?line {ok, lib1} =
compile:file(fname(LDir,lib1),[debug_info,{outdir,LDir}]),
- ?line {ok, lib2} =
+ ?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),
@@ -883,13 +883,13 @@ lib(Conf) when is_list(Conf) ->
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]]}} =
+ ?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},
+ ?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"),
@@ -934,7 +934,7 @@ lib(Conf) when is_list(Conf) ->
?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:set_library_path(s, code_path),
?line {ok, []} = xref:q(s, "U"),
?line check_state(s),
?line xref:stop(s),
@@ -1010,18 +1010,18 @@ do_read(File, Version) ->
?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},
+ ?line Erl = set([{erlang,length,1},{erlang,integer,1},
{erlang,binary_to_term,1}]),
- ?line [{erlang,binary_to_term,1},{erlang,length,1}] =
+ ?line [{erlang,binary_to_term,1},{erlang,length,1}] =
to_external(intersection(set(XU), Erl)),
- ?line xref:stop(s).
+ ?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,
+ 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},
@@ -1162,7 +1162,7 @@ read_expected(Version) ->
{POS14+17,{{read,bi,0},{read,bi,0}}}],
OK = case Version of
- abstract_v1 ->
+ abstract_v1 ->
[{POS8+3, {FF,{erlang,apply,3}}},
{POS10+1, {FF,{erlang,apply,3}}},
{POS10+6, {FF,{erlang,apply,3}}}]
@@ -1170,7 +1170,7 @@ read_expected(Version) ->
[{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}}},
@@ -1183,18 +1183,34 @@ read_expected(Version) ->
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,
+ OKB1 = [{POS13+1,{FF,{erts_debug,apply,4}}},
+ {POS13+2,{FF,{erts_debug,apply,4}}},
+ {POS13+3,{FF,{erts_debug,apply,4}}},
+ {POS1+3, {FF,{erlang,binary_to_term,1}}},
+ {POS3+1, {FF,{erlang,spawn,3}}},
+ {POS3+2, {FF,{erlang,spawn,3}}},
+ {POS3+3, {FF,{erlang,spawn_link,3}}},
+ {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}}}],
+
+ %% Operators (OTP-8647):
+ OKB = case Version of
+ abstract_v1 ->
+ [];
+ _ ->
+ [{POS13+16, {{read,bi,0},{erlang,'!',2}}},
+ {POS13+16, {{read,bi,0},{erlang,'-',1}}},
+ {POS13+16, {{read,bi,0},{erlang,self,0}}}]
+ end
+ ++ [{POS14+19, {{read,bi,0},{erlang,'+',2}}},
+ {POS14+21, {{read,bi,0},{erlang,'+',2}}},
+ {POS13+16, {{read,bi,0},{erlang,'==',2}}},
+ {POS14+15, {{read,bi,0},{erlang,'==',2}}},
+ {POS13+5, {{read,bi,0},{erlang,'>',2}}},
+ {POS14+3, {{read,bi,0},{erlang,'>',2}}}]
+ ++ OKB1 ++ OK,
{U, OK, OKB}.
@@ -1217,9 +1233,9 @@ read2(Conf) when is_list(Conf) ->
spawn_opt(fun() -> foo end, [link]),
spawn_opt(f(),
{read2,f}, [{min_heap_size,1000}]),
- spawn_opt(f(),
+ spawn_opt(f(),
fun() -> f() end, [flopp]),
- spawn_opt(f(),
+ spawn_opt(f(),
read2, f, [], []);
f() ->
%% Duplicated unresolved calls are ignored:
@@ -1237,7 +1253,7 @@ read2(Conf) when is_list(Conf) ->
?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 true = OK =:= OK2,
?line ok = check_state(s),
?line xref:stop(s),
@@ -1304,7 +1320,7 @@ replace(Conf) when is_list(Conf) ->
?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}} =
+ ?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}, []),
@@ -1312,7 +1328,7 @@ replace(Conf) when is_list(Conf) ->
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} =
+ ?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),
@@ -1332,14 +1348,14 @@ replace(Conf) when is_list(Conf) ->
?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}} =
+ ?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, _, _}} =
+ ?line {error, _, {file_error, _, _}} =
xref:replace_module(s, x, Ybeam);
- _ ->
+ _ ->
true
end,
?line ok = xref:remove_module(s, x),
@@ -1362,16 +1378,16 @@ update(Conf) when is_list(Conf) ->
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, x} = compile:file(Source, [debug_info, {outdir,Dir}]),
+
?line {ok, _} = start(s),
- ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
+ ?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
@@ -1379,7 +1395,7 @@ update(Conf) when is_list(Conf) ->
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} = compile:file(Source, [debug_info, {outdir,Dir}]),
?line {ok, [x]} = xref:update(s, []),
?line {ok, [{erlang,list_to_atom,1}]} = xref:q(s, "XU"),
@@ -1454,11 +1470,11 @@ deprecated(Conf) when is_list(Conf) ->
DF = usort(DF_3++[{{M9,t,0},{M9,f,1}}]),
?line {ok,DF} = xref:analyze(s, deprecated_function_calls),
- ?line {ok,DF_1} =
+ ?line {ok,DF_1} =
xref:analyze(s, {deprecated_function_calls,next_version}),
- ?line {ok,DF_2} =
+ ?line {ok,DF_2} =
xref:analyze(s, {deprecated_function_calls,next_major_release}),
- ?line {ok,DF_3} =
+ ?line {ok,DF_3} =
xref:analyze(s, {deprecated_function_calls,eventually}),
D = to_external(range(from_term(DF))),
@@ -1467,11 +1483,11 @@ deprecated(Conf) when is_list(Conf) ->
D_3 = to_external(range(from_term(DF_3))),
?line {ok,D} = xref:analyze(s, deprecated_functions),
- ?line {ok,D_1} =
+ ?line {ok,D_1} =
xref:analyze(s, {deprecated_functions,next_version}),
- ?line {ok,D_2} =
+ ?line {ok,D_2} =
xref:analyze(s, {deprecated_functions,next_major_release}),
- ?line {ok,D_3} =
+ ?line {ok,D_3} =
xref:analyze(s, {deprecated_functions,eventually}),
?line ok = check_state(s),
@@ -1516,11 +1532,11 @@ deprecated(Conf) when is_list(Conf) ->
DFa = DFa_3,
?line {ok,DFa} = xref:analyze(s, deprecated_function_calls),
- ?line {ok,DFa_1} =
+ ?line {ok,DFa_1} =
xref:analyze(s, {deprecated_function_calls,next_version}),
- ?line {ok,DFa_2} =
+ ?line {ok,DFa_2} =
xref:analyze(s, {deprecated_function_calls,next_major_release}),
- ?line {ok,DFa_3} =
+ ?line {ok,DFa_3} =
xref:analyze(s, {deprecated_function_calls,eventually}),
?line ok = check_state(s),
@@ -1564,11 +1580,11 @@ deprecated(Conf) when is_list(Conf) ->
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} =
+ ?line {ok,DFb_1} =
xref:analyze(s, {deprecated_function_calls,next_version}),
- ?line {ok,DFb_2} =
+ ?line {ok,DFb_2} =
xref:analyze(s, {deprecated_function_calls,next_major_release}),
- ?line {ok,DFb_3} =
+ ?line {ok,DFb_3} =
xref:analyze(s, {deprecated_function_calls,eventually}),
?line ok = check_state(s),
@@ -1599,7 +1615,7 @@ trycatch(Conf) when is_list(Conf) ->
catch
error:a -> err:e1();
error:b -> err:e2()
- after
+ after
fini:shed()
end.
">>,
@@ -1616,7 +1632,7 @@ trycatch(Conf) when is_list(Conf) ->
{{{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]}]} =
+ {{{A,A,0},{foo,foo,0}},[9]}]} =
xref:q(s, "(Lin) (E | trycatch:trycatch/0)"),
?line ok = check_state(s),
@@ -1662,7 +1678,7 @@ abstract_modules(Conf) when is_list(Conf) ->
{{{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]}]} =
+ {{{param,new,2},{param,instance,2}},[0]}]} =
xref:q(s, "(Lin) E"),
?line {ok,[{param,args,1},
{param,instance,2},
@@ -1747,10 +1763,10 @@ qlc(Conf) when is_list(Conf) ->
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}
+ 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),
+ QH2 = qlc:q([{Y} || {X,Y} <- dets:table(t),
(X > 1) or (X < 5)]),
true = qlc:info(QH1) =:= qlc:info(QH2),
dets:close(t),
@@ -1783,7 +1799,7 @@ analyze(Conf) when is_list(Conf) ->
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"}}, _} =
+ ?line {{error, _, {unknown_constant,"foo:bar/-1"}}, _} =
xref_base:analyze(S0, {use,{foo,bar,-1}}),
CopyDir = ?copydir,
@@ -1803,30 +1819,30 @@ analyze(Conf) when is_list(Conf) ->
?line {ok, rel2, S1} = xref_base:add_release(S0, Dir, [{verbose,false}]),
?line S = set_up(S1),
- ?line {ok, _} =
+ ?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, _} =
+ ?line {ok, _} =
analyze(deprecated_function_calls, [{{y,t,0},{x,t,0}}], S),
?line {ok, _} = analyze({deprecated_function_calls,next_version}, [], S),
- ?line {ok, _} =
+ ?line {ok, _} =
analyze({deprecated_function_calls,next_major_release}, [], S),
- ?line {ok, _} = analyze({deprecated_function_calls,eventually},
+ ?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, _} =
+ ?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, _} =
+ ?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, _} =
+ ?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),
@@ -1881,7 +1897,7 @@ basic(Conf) when is_list(Conf) ->
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,
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
XC_m1, LC_m1),
D2 = {F2,7},
@@ -1895,7 +1911,7 @@ basic(Conf) when is_list(Conf) ->
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,
+ ?line S2 = add_module(S1, Info2, DefAt_m2, X_m2, LCallAt_m2, XCallAt_m2,
XC_m2, LC_m2),
D4 = {F4,6},
@@ -1908,7 +1924,7 @@ basic(Conf) when is_list(Conf) ->
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,
+ ?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]},
@@ -1955,7 +1971,7 @@ basic(Conf) when is_list(Conf) ->
?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]]),
+ ?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),
@@ -1976,7 +1992,7 @@ basic(Conf) when is_list(Conf) ->
?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]),
+ ?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),
@@ -1984,7 +2000,7 @@ basic(Conf) when is_list(Conf) ->
?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),
@@ -2012,18 +2028,18 @@ basic(Conf) when is_list(Conf) ->
?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]]),
+ ?line {ok, _} = eval(f("range (closure E | ~p)", [[F1,F2]]),
[F6,F3,F7,F4,F5,UF1,UF2], S),
- ?line {ok, _} =
+ ?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",
+ ?line {ok, _} = eval("condensation (Mod) E",
[{[m1,m2,m3],[m1,m2,m3]},{[m1,m2,m3],[m17]}], S),
- ?line {ok, _} = eval("condensation closure (Mod) E",
+ ?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",
+ ?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),
@@ -2035,11 +2051,11 @@ basic(Conf) when is_list(Conf) ->
[[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("(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]",
+ ?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),
@@ -2095,7 +2111,7 @@ md(Conf) when is_list(Conf) ->
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}),
@@ -2171,7 +2187,7 @@ variables(Conf) when is_list(Conf) ->
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,
+ ?line S1 = add_module(S0, Info1, DefAt_m1, X_m1, LCallAt_m1, XCallAt_m1,
XC_m1, LC_m1),
D2 = {F2,7},
@@ -2183,11 +2199,11 @@ variables(Conf) when is_list(Conf) ->
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,
+ ?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)))",
@@ -2202,16 +2218,16 @@ variables(Conf) when is_list(Conf) ->
?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} =
+ ?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} =
+ ?line {{ok, [{predefined,_}]}, S107_0} =
xref_base:variables(S106, [predefined]),
- ?line {ok, S107_1} =
+ ?line {ok, S107_1} =
eval("TT := E, TT2 := V, TT1 := TT * TT", [E1,E2,E3], S107_0),
- ?line {{ok, [{user, ['TT', 'TT1', 'TT2']}]}, _} =
+ ?line {{ok, [{user, ['TT', 'TT1', 'TT2']}]}, _} =
xref_base:variables(S107_1),
?line {ok, S107} = xref_base:forget(S107_1),
@@ -2220,14 +2236,14 @@ variables(Conf) when is_list(Conf) ->
Beam = fname(Dir, "lib1.beam"),
?line copy_file(fname(Dir, "lib1.erl"), Beam),
- ?line {ok, S108} =
+ ?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",
+ ?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']),
@@ -2289,7 +2305,7 @@ unused_locals(Conf) when is_list(Conf) ->
?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),
@@ -2303,7 +2319,7 @@ 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}]),
+ ?line ok = xref:set_default(s, [{verbose,false}, {warnings, false}]),
%% Parse error messages.
?line "Invalid regular expression \"add(\"" ++ _ =
@@ -2332,7 +2348,7 @@ format_error(Conf) when is_list(Conf) ->
%% Other messages
?line 'Variable \'QQ\' used before set\n' =
fatom(xref:q(s,"QQ")),
- ?line 'Unknown constant a\n' =
+ ?line 'Unknown constant a\n' =
fatom(xref:q(s,"{a} of E")),
%% Testing xref_parser:t2s/1.
@@ -2341,12 +2357,12 @@ format_error(Conf) when is_list(Conf) ->
?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" =
+ "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" =
+ "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")),
@@ -2360,11 +2376,11 @@ format_error(Conf) when is_list(Conf) ->
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)"}} =
+ ?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"}} =
+ ?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)"),
@@ -2421,7 +2437,7 @@ eval(Query, E, S) ->
?format("------------------------------~n", []),
?format("Evaluating ~p~n", [Query]),
?line {Answer, NewState} = xref_base:q(S, Query, [{verbose, false}]),
- {Reply, Expected} =
+ {Reply, Expected} =
case Answer of
{ok, R} when is_list(E) ->
{unsetify(R), sort(E)};
@@ -2430,7 +2446,7 @@ eval(Query, E, S) ->
{error, _Module, Reason} ->
{element(1, Reason), E}
end,
- if
+ if
Reply =:= Expected ->
?format("As expected, got ~n~p~n", [Expected]),
{ok, NewState};
@@ -2442,7 +2458,7 @@ eval(Query, E, S) ->
analyze(Query, E, S) ->
?format("------------------------------~n", []),
?format("Evaluating ~p~n", [Query]),
- ?line {{ok, L}, NewState} =
+ ?line {{ok, L}, NewState} =
xref_base:analyze(S, Query, [{verbose, false}]),
case {unsetify(L), sort(E)} of
{X,X} ->
@@ -2461,7 +2477,7 @@ unsetify(S) ->
%% Note: assumes S has been set up; the new state is not returned
eval(Query, S) ->
- ?line {{ok, Answer}, _NewState} =
+ ?line {{ok, Answer}, _NewState} =
xref_base:q(S, Query, [{verbose, false}]),
unsetify(Answer).
@@ -2514,7 +2530,7 @@ check_state(S) ->
functions_mode_check(S, Info)
end.
-%% The manual mentions some facts that should always hold.
+%% The manual mentions some facts that should always hold.
%% Here they are again.
functions_mode_check(S, Info) ->
%% F = L + X,
@@ -2526,7 +2542,7 @@ functions_mode_check(S, Info) ->
?line {ok, V} = xref:q(S, "X + L + B + U"),
%% X, L, B and U are disjoint.
- ?line {ok, []} =
+ ?line {ok, []} =
xref:q(S, "X * L + X * B + X * U + L * B + L * U + B * U"),
%% V = UU + XU + LU,
@@ -2577,11 +2593,11 @@ functions_mode_check(S, Info) ->
?line {Local, Exported} = info(Info, no_functions),
?line LX = Local+Exported,
- ?line {ok, LXs} = xref:q(S, 'Extra = _:module_info/"(0|1)" + LM,
+ ?line {ok, LXs} = xref:q(S, 'Extra = _:module_info/"(0|1)" + LM,
# (F - Extra)'),
?line true = LX =:= LXs,
- ?line {LocalCalls, ExternalCalls, UnresCalls} =
+ ?line {LocalCalls, ExternalCalls, UnresCalls} =
info(Info, no_function_calls),
?line LEU = LocalCalls + ExternalCalls + UnresCalls,
?line {ok, LEU} = xref:q(S, "# LC + # XC"),
@@ -2635,7 +2651,7 @@ check_count(S) ->
%% {ok, A} = xref:q(S, 'A'),
{ok, M} = xref:q(S, 'AM'),
- {ok, _} = xref:q(S,
+ {ok, _} = xref:q(S,
"Extra := _:module_info/\"(0|1)\" + LM"),
%% info/1:
@@ -2670,7 +2686,7 @@ check_count(S) ->
ok.
info_module([M | Ms], S) ->
- {ok, NoCalls} = per_module("T = (E | ~p : Mod), # (XLin) T + # (LLin) T",
+ {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),
@@ -2719,14 +2735,14 @@ start(Server) ->
end.
add_erts_code_path(KernelPath) ->
- VersionDirs =
+ VersionDirs =
filelib:is_dir(
filename:join(
[code:lib_dir(),
lists:flatten(
["kernel-",
- [X ||
- {kernel,_,X} <-
+ [X ||
+ {kernel,_,X} <-
application_controller:which_applications()]])])),
case VersionDirs of
true ->
@@ -2746,5 +2762,5 @@ add_erts_code_path(KernelPath) ->
[KernelPath]
end
end.
-
-
+
+
diff --git a/lib/tools/test/xref_SUITE_data/read/read.erl b/lib/tools/test/xref_SUITE_data/read/read.erl
index 4a0cc280c3..19694c9e25 100644
--- a/lib/tools/test/xref_SUITE_data/read/read.erl
+++ b/lib/tools/test/xref_SUITE_data/read/read.erl
@@ -106,13 +106,13 @@ funfuns() ->
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), %
+ 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}
@@ -125,7 +125,7 @@ funfuns() ->
bi() when length([]) > 17 ->
foo:module_info(),
module_info(),
- A = tjo,
+ A = true andalso tjo ,
t:foo(A),
case true of
true when integer(1) ->
@@ -133,7 +133,7 @@ bi() when length([]) > 17 ->
false ->
X = flopp
end,
- X == A;
+ self() ! X == -A orelse false;
bi() ->
%% POS14=POS13+18
Z = fun(Y) -> Y end,
@@ -159,7 +159,7 @@ bi() ->
D + E + F.
%bi() ->
% %% POS15=POS14+13
-% try
+% try
% foo:t(),
% bar:t()
% of
@@ -169,7 +169,7 @@ bi() ->
% foo:t()
% catch
% {'EXIT',_} -> bar:t()
-% end.
+% end.
local() ->
true.
diff --git a/lib/tv/src/tv_io_lib_format.erl b/lib/tv/src/tv_io_lib_format.erl
index 5042fd3f9d..e043d9296e 100644
--- a/lib/tv/src/tv_io_lib_format.erl
+++ b/lib/tv/src/tv_io_lib_format.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(tv_io_lib_format).
@@ -188,7 +188,7 @@ indentation([], I) -> I.
term(T, none, _Adj, none, _Pad) -> T;
term(T, none, Adj, P, Pad) -> term(T, P, Adj, P, Pad);
-term(T, F, Adj, none, Pad) -> term(T, F, Adj, min(flat_length(T), F), Pad);
+term(T, F, Adj, none, Pad) -> term(T, F, Adj, erlang:min(flat_length(T), F), Pad);
term(T, F, Adj, P, Pad) when F >= P ->
adjust_error(T, F, Adj, P, Pad).
@@ -316,7 +316,7 @@ fwrite_g(Fl, F, Adj, P, Pad) ->
string(S, none, _Adj, none, _Pad) -> S;
string(S, F, Adj, none, Pad) ->
- string(S, F, Adj, min(flat_length(S), F), Pad);
+ string(S, F, Adj, erlang:min(flat_length(S), F), Pad);
string(S, none, _Adj, P, Pad) ->
string:left(flatten(S), P, Pad);
string(S, F, Adj, P, Pad) when F >= P ->
@@ -362,9 +362,6 @@ reverse([H|T], Stack) ->
reverse(T, [H|Stack]);
reverse([], Stack) -> Stack.
-min(L, R) when L < R -> L;
-min(_, R) -> R.
-
%% flatten(List)
%% Flatten a list.
diff --git a/lib/tv/src/tv_pb.erl b/lib/tv/src/tv_pb.erl
index 34db8d0772..78a27185dc 100644
--- a/lib/tv/src/tv_pb.erl
+++ b/lib/tv/src/tv_pb.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(tv_pb).
@@ -522,7 +522,7 @@ handle_col_resizing(RbtnId, RealCol, VirtualCol, Xpos, ProcVars) ->
get_xdiff(Id, Btn, LastXdiff, LineId, LineXpos, MinAllowedXdiff) ->
receive
{gs, Id, motion, {resbtn, _RealCol, _VirtCol, _OldXpos}, [NewXdiff | _T]} ->
- UsedXdiff = max(MinAllowedXdiff, NewXdiff),
+ UsedXdiff = erlang:max(MinAllowedXdiff, NewXdiff),
gs:config(LineId, [{x, LineXpos + UsedXdiff}]),
get_xdiff(Id, Btn, UsedXdiff, LineId, LineXpos, MinAllowedXdiff);
{gs, Id, buttonrelease, _Data, [Btn | _T]} ->
@@ -658,28 +658,3 @@ update_vbtns(Msg, ProcVars) ->
update_keys(Msg, ProcVars) ->
#pb_key_info{list_of_keys = KeyList} = Msg,
tv_pb_funcs:update_keys(KeyList, ProcVars).
-
-
-
-
-
-
-
-
-%%======================================================================
-%% Function:
-%%
-%% Return Value:
-%%
-%% Description:
-%%
-%% Parameters:
-%%======================================================================
-
-
-max(A, B) when A >= B ->
- A;
-max(_, B) ->
- B.
-
-
diff --git a/lib/tv/src/tv_pg_gridfcns.erl b/lib/tv/src/tv_pg_gridfcns.erl
index 809403fd96..ab88e2864f 100644
--- a/lib/tv/src/tv_pg_gridfcns.erl
+++ b/lib/tv/src/tv_pg_gridfcns.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(tv_pg_gridfcns).
@@ -98,7 +98,7 @@ init_grid(GridParentId, GridWidth,
nof_rows_shown = NofRowsShown
},
- NewNofCols = max(length(ColsShown), NofCols),
+ NewNofCols = erlang:max(length(ColsShown), NofCols),
% The GridColWidths list shall contain the current width of each frame.
NewColWidths = update_col_widths(ColsShown, ColWidths, FirstColShown,
@@ -270,7 +270,7 @@ resize_grid_column(RealCol, VirtualCol, Xdiff, ProcVars) ->
lists_as_strings = ListAsStr} = GridP,
% Get new width!
- Width = min(MaxColWidth, max((lists:nth(VirtualCol, ColWidths) + Xdiff),
+ Width = erlang:min(MaxColWidth, erlang:max((lists:nth(VirtualCol, ColWidths) + Xdiff),
MinColWidth)),
% Resize the column.
@@ -1336,7 +1336,7 @@ resize_all_grid_columns(RealCol, [ColWidth | Tail], ColFrameIds, MaxColWidth, Mi
resize_one_column(RealCol, Width, ColFrameIds, MaxW, MinW) ->
- NewWidthOfCol = min(MaxW, max(Width, MinW)),
+ NewWidthOfCol = erlang:min(MaxW, erlang:max(Width, MinW)),
case length(ColFrameIds) of
RealCol ->
done;
@@ -1894,46 +1894,3 @@ extract_ids_for_one_row(N, [ColIds | Tail]) ->
%%%---------------------------------------------------------------------
%%% END of functions used to create the grid.
%%%---------------------------------------------------------------------
-
-
-
-
-
-%%======================================================================
-%% Function:
-%%
-%% Return Value:
-%%
-%% Description:
-%%
-%% Parameters:
-%%======================================================================
-
-
-max(A, B) when A > B ->
- A;
-max(_, B) ->
- B.
-
-
-
-
-
-
-
-%%======================================================================
-%% Function:
-%%
-%% Return Value:
-%%
-%% Description:
-%%
-%% Parameters:
-%%======================================================================
-
-
-min(A, B) when A < B ->
- A;
-min(_, B) ->
- B.
-
diff --git a/lib/wx/c_src/Makefile.in b/lib/wx/c_src/Makefile.in
index 5a0b4ce8ef..8710641b57 100644
--- a/lib/wx/c_src/Makefile.in
+++ b/lib/wx/c_src/Makefile.in
@@ -167,7 +167,7 @@ release_spec: opt
$(INSTALL_DIR) $(RELSYSDIR)/priv/$(SYS_TYPE)
$(INSTALL_DATA) ../priv/erlang-logo32.png $(RELSYSDIR)/priv/
$(INSTALL_DATA) ../priv/erlang-logo64.png $(RELSYSDIR)/priv/
- $(INSTALL_DATA) $(TARGET_DIR)/$(TARGET_API)$(SO_EXT) $(RELSYSDIR)/priv/$(SYS_TYPE)
+ $(INSTALL_PROGRAM) $(TARGET_DIR)/$(TARGET_API)$(SO_EXT) $(RELSYSDIR)/priv/$(SYS_TYPE)
release_docs_spec:
diff --git a/lib/wx/src/wx_object.erl b/lib/wx/src/wx_object.erl
index 1f0b7922a0..bfd38960dd 100644
--- a/lib/wx/src/wx_object.erl
+++ b/lib/wx/src/wx_object.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_object.erl
@@ -321,7 +321,8 @@ loop(Parent, Name, State, Mod, Time, Debug) ->
_Msg when Debug =:= [] ->
handle_msg(Msg, Parent, Name, State, Mod);
_Msg ->
- Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name, {in, Msg}),
+ Debug1 = sys:handle_debug(Debug, fun print_event/3,
+ Name, {in, Msg}),
handle_msg(Msg, Parent, Name, State, Mod, Debug1)
end.
@@ -410,12 +411,12 @@ handle_msg({'$gen_call', From, Msg}, Parent, Name, State, Mod, Debug) ->
Debug1 = reply(Name, From, Reply, NState, Debug),
loop(Parent, Name, NState, Mod, Time1, Debug1);
{noreply, NState} ->
- Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name,
- {noreply, NState}),
+ Debug1 = sys:handle_debug(Debug, fun print_event/3,
+ Name, {noreply, NState}),
loop(Parent, Name, NState, Mod, infinity, Debug1);
{noreply, NState, Time1} ->
- Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name,
- {noreply, NState}),
+ Debug1 = sys:handle_debug(Debug, fun print_event/3,
+ Name, {noreply, NState}),
loop(Parent, Name, NState, Mod, Time1, Debug1);
{stop, Reason, Reply, NState} ->
{'EXIT', R} =
@@ -437,12 +438,12 @@ handle_no_reply({noreply, NState}, Parent, Name, _Msg, Mod, _State, []) ->
handle_no_reply({noreply, NState, Time1}, Parent, Name, _Msg, Mod, _State, []) ->
loop(Parent, Name, NState, Mod, Time1, []);
handle_no_reply({noreply, NState}, Parent, Name, _Msg, Mod, _State, Debug) ->
- Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name,
- {noreply, NState}),
+ Debug1 = sys:handle_debug(Debug, fun print_event/3,
+ Name, {noreply, NState}),
loop(Parent, Name, NState, Mod, infinity, Debug1);
handle_no_reply({noreply, NState, Time1}, Parent, Name, _Msg, Mod, _State, Debug) ->
- Debug1 = sys:handle_debug(Debug, {gen_server, print_event}, Name,
- {noreply, NState}),
+ Debug1 = sys:handle_debug(Debug, fun print_event/3,
+ Name, {noreply, NState}),
loop(Parent, Name, NState, Mod, Time1, Debug1);
handle_no_reply(Reply, _Parent, Name, Msg, Mod, State, Debug) ->
handle_common_reply(Reply, Name, Msg, Mod, State,Debug).
@@ -462,8 +463,8 @@ handle_common_reply(Reply, Name, Msg, Mod, State, Debug) ->
%% @hidden
reply(Name, {To, Tag}, Reply, State, Debug) ->
reply({To, Tag}, Reply),
- sys:handle_debug(Debug, {gen_server, print_event}, Name,
- {out, Reply, To, State} ).
+ sys:handle_debug(Debug, fun print_event/3,
+ Name, {out, Reply, To, State}).
%%-----------------------------------------------------------------
@@ -485,6 +486,29 @@ system_code_change([Name, State, Mod, Time], _Module, OldVsn, Extra) ->
Else -> Else
end.
+%%-----------------------------------------------------------------
+%% Format debug messages. Print them as the call-back module sees
+%% them, not as the real erlang messages. Use trace for that.
+%%-----------------------------------------------------------------
+print_event(Dev, {in, Msg}, Name) ->
+ case Msg of
+ {'$gen_call', {From, _Tag}, Call} ->
+ io:format(Dev, "*DBG* ~p got call ~p from ~w~n",
+ [Name, Call, From]);
+ {'$gen_cast', Cast} ->
+ io:format(Dev, "*DBG* ~p got cast ~p~n",
+ [Name, Cast]);
+ _ ->
+ io:format(Dev, "*DBG* ~p got ~p~n", [Name, Msg])
+ end;
+print_event(Dev, {out, Msg, To, State}, Name) ->
+ io:format(Dev, "*DBG* ~p sent ~p to ~w, new state ~w~n",
+ [Name, Msg, To, State]);
+print_event(Dev, {noreply, State}, Name) ->
+ io:format(Dev, "*DBG* ~p new state ~w~n", [Name, State]);
+print_event(Dev, Event, Name) ->
+ io:format(Dev, "*DBG* ~p dbg ~p~n", [Name, Event]).
+
%%% ---------------------------------------------------
%%% Terminate the server.
%%% ---------------------------------------------------
@@ -581,12 +605,15 @@ dbg_opts(Name, Opts) ->
%%-----------------------------------------------------------------
format_status(Opt, StatusData) ->
[PDict, SysState, Parent, Debug, [Name, State, Mod, _Time]] = StatusData,
- NameTag = if is_pid(Name) ->
- pid_to_list(Name);
- is_atom(Name) ->
- Name
- end,
- Header = lists:concat(["Status for generic server ", NameTag]),
+ StatusHdr = "Status for wx object ",
+ Header = if
+ is_pid(Name) ->
+ lists:concat([StatusHdr, pid_to_list(Name)]);
+ is_atom(Name); is_list(Name) ->
+ lists:concat([StatusHdr, Name]);
+ true ->
+ {StatusHdr, Name}
+ end,
Log = sys:get_debug(log, Debug, []),
Specfic =
case erlang:function_exported(Mod, format_status, 2) of
diff --git a/system/doc/reference_manual/expressions.xml b/system/doc/reference_manual/expressions.xml
index b56b8acbf0..714ecccaf6 100644
--- a/system/doc/reference_manual/expressions.xml
+++ b/system/doc/reference_manual/expressions.xml
@@ -217,12 +217,16 @@ lists:keysearch(Name, 1, List)</code>
<p>In the second form of function calls,
<c>ExprF(Expr1,...,ExprN)</c>, <c>ExprF</c> must be an atom or
evaluate to a fun.</p>
+
<p>If <c>ExprF</c> is an atom the function is said to be called by
- using the <em>implicitly qualified function name</em>. If
- <c>ExprF/N</c> is the name of a function explicitly or
- automatically imported from module <c>M</c>, then the call is
- short for <c>M:ExprF(Expr1,...,ExprN)</c>. Otherwise,
- <c>ExprF/N</c> must be a locally defined function. Examples:</p>
+ using the <em>implicitly qualified function name</em>. If the
+ function <c>ExprF</c> is locally defined, it is called.
+ Alternatively if <c>ExprF</c> is explicitly imported from module
+ <c>M</c>, <c>M:ExprF(Expr1,...,ExprN)</c> is called. If
+ <c>ExprF</c> is neither declared locally nor explicitly
+ imported, <c>ExprF</c> must be the name of an automatically
+ imported BIF. Examples:</p>
+
<code type="none">
handle(Msg, State)
spawn(m, init, [])</code>
@@ -238,16 +242,85 @@ Fun2([1,2], [3,4])
fun lists:append/2([1,2], [3,4])
=> [1,2,3,4]</code>
- <p>To avoid possible ambiguities, the fully qualified function
- name must be used when calling a function with the same name as
- a BIF, and the compiler does not allow defining a function with
- the same name as an explicitly imported function.</p>
+
<p>Note that when calling a local function, there is a difference
- between using the implicitly or fully qualified function name, as
- the latter always refers to the latest version of the module. See
- <seealso marker="code_loading">Compilation and Code Loading</seealso>.</p>
+ between using the implicitly or fully qualified function name, as
+ the latter always refers to the latest version of the module. See
+ <seealso marker="code_loading">Compilation and Code Loading</seealso>.</p>
+
<p>See also the chapter about
<seealso marker="functions#eval">Function Evaluation</seealso>.</p>
+
+ <section>
+ <title>Local Function Names Clashing With Auto-imported BIFs</title>
+ <p>If a local function has the same name as an auto-imported BIF,
+ the semantics is that implicitly qualified function calls are
+ directed to the locally defined function, not to the BIF. To avoid
+ confusion, there is a compiler directive available,
+ <c>-compile({no_auto_import,[F/A]})</c>, that makes a BIF not
+ being auto-imported. In certain situations, such a compile-directive
+ is mandatory.</p>
+
+ <warning><p>Before OTP R14A (ERTS version 5.8), an implicitly
+ qualified function call to a function having the same name as an
+ auto-imported BIF always resulted in the BIF being called. In
+ newer versions of the compiler the local function is instead
+ called. The change is there to avoid that future additions to the
+ set of auto-imported BIFs does not silently change the behavior
+ of old code.</p>
+
+ <p>However, to avoid that old (pre R14) code changed it's
+ behavior when compiled with OTP version R14A or later, the
+ following restriction applies: If you override the name of a BIF
+ that was auto-imported in OTP versions prior to R14A (ERTS version
+ 5.8) and have an implicitly qualified call to that function in
+ your code, you either need to explicitly remove the auto-import
+ using a compiler directive, or replace the call with a fully
+ qualified function call, otherwise you will get a compilation
+ error. See example below:</p> </warning>
+
+ <code type="none">
+-export([length/1,f/1]).
+
+-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
+
+length([]) ->
+ 0;
+length([H|T]) ->
+ 1 + length(T). %% Calls the local funtion length/1
+
+f(X) when erlang:length(X) > 3 -> %% Calls erlang:length/1,
+ %% which is allowed in guards
+ long.</code>
+
+ <p>The same logic applies to explicitly imported functions from
+ other modules as to locally defined functions. To both import a
+ function from another module and have the function declared in the
+ module at the same time is not allowed.</p>
+
+ <code type="none">
+-export([f/1]).
+
+-compile({no_auto_import,[length/1]}). % erlang:length/1 no longer autoimported
+
+-import(mod,[length/1]).
+
+f(X) when erlang:length(X) > 33 -> %% Calls erlang:lenght/1,
+ %% which is allowed in guards
+
+ erlang:length(X); %% Explicit call to erlang:length in body
+
+f(X) ->
+ length(X). %% mod:length/1 is called</code>
+
+
+ <p>For auto-imported BIFs added to Erlang in release R14A and thereafter,
+ overriding the name with a local function or explicit import is always
+ allowed. However, if the <c>-compile({no_auto_import,[F/A])</c>
+ directive is not used, the compiler will issue a warning whenever
+ the function is called in the module using the implicitly qualified
+ function name.</p>
+ </section>
</section>
<section>
diff --git a/xcomp/erl-xcomp-mips-linux.conf b/xcomp/erl-xcomp-mips-linux.conf
new file mode 100644
index 0000000000..3ac057bb4c
--- /dev/null
+++ b/xcomp/erl-xcomp-mips-linux.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-mips-linux.conf
+## Author: Matthias Lang
+##
+## -----------------------------------------------------------------------------
+## 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=mips-linux
+
+# * `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=
+
+# * `CFLAGS' - C compiler flags.
+CFLAGS=-Os
+
+# * `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=
+
+## -----------------------------------------------------------------------------